Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык Си. Лабораторные работы / Справочник. Часть 2 (СПбГУТ).doc
Скачиваний:
47
Добавлен:
10.09.2019
Размер:
801.79 Кб
Скачать

2.5. Вложенные циклы

Вложенными циклами называется циклическая конструкция, содержащая не менее двух циклов. В целом такая конструкция является циклом (его принято называть внешним), в теле которого находятся один или несколько других циклов (их принято называть внутренними). Любой внутренний цикл может быть построен по системе вложенных циклов.

Пример Табулирование функции, содержащей суммы

Постановка задачи. Выполнить табулирование в n равноотстоящих точках на отрезке [xn, xk] функции

Решение. Обозначим через s1 левую сумму, а через s2 – правую сумму. При решении этой задачи необходимо организовать три циклических процесса. Первый из этих процессов – цикл табулирования заданной функции. Именно этот цикл определяет существо решаемой задачи. Два других цикла необходимы для вычисления сумм s1 и s2. Между последними циклами имеется существенное различие. Сумма s1 должна вычисляться заново для каждого нового значения x, а сумма s2 не должна. В связи с этим вычисление суммы s2 может быть вынесено из цикла табулирования.

Таким образом, программа решения этой задачи должна содержать два цикла: цикл для вычисления суммы s2, за которым должен следовать цикл табулирования, построенный по схеме вложенных циклов. Внешний цикл должен выполнять табулирование, а внутренний цикл – вычислять сумму s1.

#include<stdio.h> #include<math.h> int main(void) { double xn; printf(“%s”, “xn =”); scanf(“%lf”, &xn); double xk; printf(“%s”, “xk = ”); scanf(“%lf”, &xk); int n; printf(“n =”, “n = ”); scanf(“%d”, &n); int m; printf(“m =”); scanf(“%d”, &m); double s2=0 ; for(int k = 1; k <= m; k++)//область видимости переменной k s2 += k / (k + 1.0); //ограничена этим циклом double dx = (xk – xn)/(n-1); double x = xn; printf(“%5s%10s%15s\n”,”Num”, “X”, “Y”); for(int i = 1;i <= n; i++) // начало области видимости { // переменной i double s1 = 0; for(int j = 1; j <= m; j++)//область видимости //переменной j ограничена s1 += j /(j + x * x); // этим циклом double y = 2 * x + sqrt(x * x + s1 + s2); printf(“%5d%10.2f%15.2f\n”, I, x, y); x += dx ; } //конец области видимости переменной I getchar(); return 0; }

2.6. Работа с функциями

При разработке функций следует придерживаться следующих рекомендаций:

  • Функция, как правило, должна решать только одну задачу.

  • Обмен данными между функцией и точкой вызова должен выполняться через ее параметры и возвращаемое значение.

  • В функциях, как правило, не следует совмещать: a) ввод и обработку, б) обработку и вывод результатов.

2.6.1. Преобразование программы в функцию пользователя

Подобная задача нередко возникает на практике. Автору программы могут предложить оформить полученное решение в виде функции. Приведем пример.

Постановка задачи. Оформить в виде функции решение задачи о вычислении суммы цифр натурального числа (см. пример 2 раздела 2.4).

Решение. Разработка функции включает в себя разработку интерфейса и реализации. В рассматриваемом примере по существу требуется разработать только интерфейс функции. Элементы реализации в значительной степени могут быть заимствованы из программы, приведенной в разделе 2.4.

В разработке заголовка функции можно выделить следующие этапы.

  • Выбрать имя функции.

  • Определить состав входных и выходных данных.

  • Определить будет ли функция иметь возвращаемое значение.

  • Определить параметры функции.

Реализация функции в нашем случае сведется к выбору локальных переменных и переносу элементов управления из программы в тело функции.

Имя функции должно раскрывать существо решаемой задачи. В нашем случае подходящим именем будет summa_digits.

Перейдем к рассмотрению данных, которыми функция должна обмениваться с точкой вызова. К их числу будут относиться: исходное число n (входные данные) и вычисленная сумма (выходные данные).

В нашем случае результатом вычислений является скалярная величина, которую можно вернуть в точку вызова с помощью возвращаемого значения функции. Итак, функция должна возвращать значение типа int.

Входные данные функции представлены одним числом n. Отсюда следует, что функция должна иметь только один формальный параметр int n. Теперь можно написать заголовок функции.

int summa_digits (int n)

Разработку реализации функции начнем с определения ее локальных переменных. Кандидатами для включения в их число являются все локальные переменные функции main() исходной программы, а именно, n и s. В связи с тем, что переменная n стала формальным параметром, необходимость в локальной переменной n отпадает.

Все действия, составляющие существо алгоритма вычислений исходной программы, могут быть перенесены в тело разрабатываемой функции. Исключение составляют операции ввода и вывода. Необходимость в них отпадает. Их работа выполняется интерфейсными элементами функции.

Ниже показан программный код разработанной функции.

Int summa_digits(int n) { int s = 0; do { s += n % 10; }while(n /= 10); return s; }

Перейдем к разработке функции main(), которая должна вызывать функцию summa_digits(). Предположим, что обе функции будут находиться в одном исходном файле. В этом случае возникает вопрос о их взаимном расположении. Представляется целесообразным текст программы всегда начинать с функции main(). Дело в том, что знакомство читателя с программой должно начинаться всегда с функции main(). Анализ этой функции позволит программисту составить общее представление о программе. Такой порядок следования функций предусмотрен в программе, которая приведена ниже. Для обеспечения корректной компиляции вызова функции summa_digits() ее прототип приведен в начале программы.

#include<stdio.h> int summa_digits(int n); int main(void) { int n; printf(“%s”, “n=”); scanf(“%d”, &n); printf(“Summa digits = %d\n”, summa_digits(n)); getchar(); return 0; } int summa_digits(int n) { int s = 0; do { s += n % 10; }while(n /= 10); return s; }