Дипломы, курсовые, рефераты, контрольные...
Срочная помощь в учёбе

Основные алгоритмические структуры

РефератПомощь в написанииУзнать стоимостьмоей работы

Директива ttdefine определяет макрос. Она позволяет связать указанный идентификатор (замещаемую часть) с последовательностью лексем (замещающей частью). В результате все вхождения данного идентификатора, встречающиеся после этой директивы, будут заменены на указанные лексемы. Директива может быть записана в двух формах: простого макроса и макроса с параметрами. Директива #ifdef обрабатывает часть… Читать ещё >

Основные алгоритмические структуры (реферат, курсовая, диплом, контрольная)

Обычно операторы программы выполняются последовательно один за другим. Однако часто требуется передать управление оператору, не следующему по порядку. Для реализации такой передачи используется оператор безусловного перехода goto. Синтаксис оператора:

goto ;

Метка в программе записывается в начале строки и отделяется от операторов двоеточием. Например:

i = 5 ;

goto ml;

j =10; // Никогда не выполняется.

ml: i+=3;

Многократное использование в программе операторов goto приводит к большим трудностям в сопровождении программ, поэтому, в соответствии с принципами структурного программирования, применение оператора goto считается нежелательным. Тем не менее в исключительных случаях (в программах со множественным вложением условных операторов) его применение может значительно сократить размер кода и улучшить его читаемость.

В структурном программировании выделяют три вида алгоритмических (управляющих) структур:

  • • структура следования;
  • • структура ветвления;
  • • структура повторения.

Структура следования, представленная на рис. 5.2, встроена в язык С и означает режим последовательного выполнения операторов программы.

Структура ветвления (выбора) служит для программирования разветвляющихся вычислительных процессов и реализована в виде трех структур:

  • • структура с единственным выбором (рис. 5.3) выполняет некоторое действие, если условие истинно, и игнорирует его, если условие ложно;
  • • структура с двойным выбором (рис. 5.4) выполняет одно действие, если условие истинно, и второе действие, если условие ложно;
Структура следования Рис. 5.3. Структура.

Рис. 5.2. Структура следования Рис. 5.3. Структура с единственным выбором.

• структура с множественным выбором (рис. 5.5) выполняет выбор действия среди множества действий.

Структура с единственным выбором реализуется с помощью условного оператора if. Синтаксис:

if ().

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

Примечание: в конструкциях языка С под оператором может пониматься н блок операторов — последовательность действий, заключенная в фигурные скобки. Синтаксис:

{.

Объявления и определения данных Операторы.

}.

Такая конструкция позволяет указать выполнение нескольких операторов там, где, но синтаксису может быть только один. Объявления и определения данных, заданные в блоке, действуют только в этом блоке.

С помощью блока операторов в условном операторе if можно задать выполнение нескольких операторов при истинном значении выражения.

Пример 5.4.1

Ввести число X и вычислить У, равное.

to.

При X, меньшем -10, заменить число X на X2.

#include.

#include int main ().

{.

float X, Y;

scanf («%f», &X); // ввод числа X if (X < 10).

X = X * X;

Y = sqrt (X — 10);

// Y присваивается значение функции квадратного корня // из Х-10.

printf («%f» / Y); // вывод значения Y return 0;

Ввести числа X и У и вычислить Z, равное.

Основные алгоритмические структуры.

При X, равном (У + 1), число X увеличить в два раза, а число У уменьшить в два раза.

#include int main ().

{.

float X, Y, Z;

scanf («%f %f», &X, &Y); //ввод чисел X и Y if (X == (Y + 1)) // при X=Y+1 выполняется блок // операторов.

{.

X=X*2; //X увеличивается в 2 раза.

Y = Y / 2; // Y уменьшается в 2 раза.

}.

Z = (X+Y) / (X-Y-1); // вычисление значения Z.

printf («%!», Z); // вывод числа Z.

return 0;

>_.

Структура с двойным выбором реализуется с помощью условного оператора if — else (см. рис. 5.4). Синтаксис:

if (); elseconepaTop 2>;

Структура с двойным выбором.

Рис 5.4. Структура с двойным выбором.

При выполнении этого оператора сначала вычисляется значение выражения, стоящего после if. Если значение выражения истинно (отлично от 0), то выполняется оператор1, в противном случае выполняется оператор2.

Пример 5.4.3

Ввести числа X и К, числу Z присвоить значение, равное половине наибольшего из введенных чисел.

#include int main{).

{.

float X, Y, Z;

scanf («%f %f», &X, &Y); // ввод чисел X и Y.

if (X > Y) // если X > Y, то X — наибольшеее Z = X / 2; else.

Z = Y / 2; // иначе Y наибольшее.

printf («%f», Z); return 0;

}.

Пример 5.4.4

Ввести числа X и У, нс равные друг другу. Наибольшее число уменьшить в два раза, а наименьшее — увеличить в два раза.

#include int main ().

{.

float X, Y;

scanf («%f %f», &X, &Y); // ввод чисел X и Y if (X>Y) // X — наибольшее, выполняется блок.

// операторов.

{.

X = X / 2;

Y = Y * 2;

}.

else // Y — наибольшее, выполняется блок операторов.

{.

Y = Y / 2;

X = X * 2;

}.

printf («%f %f», X, Y);

return 0;

}_.

Оператор if может быть вложенным. Это означает, что данный оператор может быть включен в конструкцию if или else другого условного оператора. При этом компилятор связывает каждое ключевое слово else с наиболее близким if, для которого нет else.

Ввести три числа а, Ь, с, не равные друг другу. Найти сумму максимального и минимального из этих чисел.

#include int main<).

{.

float а, b, c, s; // s — сумма максимального.

// и минимального числа.

scanf («%f %f %f», &a, &b, &c); // ввод исходных чисел if (a>

if (a> // максимальное число a.

if (b>c) // минимальное число с s = a + с;

else // минимальное число b.

s = a + b;

else // максимальное число с, минимальное — b.

s = с + b;

else.

if (b>c) // максимальное число b.

if (a> // минимальное число с s = b + с ;

else // минимальное число a.

s = b + a ;

else // максимальное число с, минимальное — а.

s = с + а; printf («%f», s); return 0;

При составлении выражения в операторе if можно использовать логические операции И и ИЛИ, позволяющие объединить несколько простых выражений в одно составное. Программа, реализующая предыдущий пример, с помощью этих операций может быть записана в следующем виде:

#include int main ().

{.

float a, br c, s;

scanf («%f %f %f» / &a, &b, &c);

if ((a > b) && (b > c)) s = a + c ;

if ((a > c) && (c > b)) s = a + b ;

if ((b > a) ScSc (a > c)) s = b + c ;

if ((b > c) ScSc (c > a)) s = b + a ;

if ((c > a) ScSc (a > b)) s = c + b ;

if ((с > b) && (b > a)) s = c + a; printf («%f», s); return 0;

}.

При использовании логических операций И и ИЛИ следует иметь в виду, что выражение может не вычисляться до конца. Действительно:

  • • если значение левого операнда операции && равно FALSE (нулю), то значение правого операнда не вычисляется, так как результат всей операции от него не зависит;
  • • если значение левого операнда операции || равно TRUE (не равно нулю), то значение правого операнда также не вычисляется.

Рассмотрим еще один пример использования вложенного оператора if.

Пример 5.4.6.

Ввести коэффициенты квадратного уравнения а, b, с. Найти корни уравнения.

#include.

#include int main{).

{.

int a, b, c, d; float xl, x2;

scanf («%d %d %d» ,&a, &b, &c); // ввод коэффициентов.

// уравнения.

d=b*b-4*a*c; // вычисление дискриминанта.

if (d<0) // если дискриминант меньше 0, корней нет.

printf («net korney «); else.

if (d==0) // если дискриминант равен 0Г у уравнения.

// один корень.

printf («l korn: %d «, -b/(2*a)); else// в противном случае у уравнения два корня printf («2 korna: %f %f «, (-b+sqrt (d))/(2*a) ,.

(-b-sqrt (d)) / (2*a)) ;

Структура с множественным выбором (см. рис. 5.5) реализуется с помощью оператора выбора switch-case. Синтаксис:

switch ().

{.

сазе:

[;] сазе:

[].

[default;].

}.

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

Структура с множественным выбором.

Рис 5.5. Структура с множественным выбором Оператор switch сравнивает значение выражения, стоящего после switch, со всеми значениями (метками), перечисленными с помощью ключевых слов case. Как только значение выражения совпадает с какой-либо меткой, управление передается оператору, следующему за этой меткой. Если значение выражения не совпадает ни с одной меткой, то управление передается оператору с меткой default (если такая метка есть) или оператору, следующему за оператором switch (если метка default отсутствует).

Как выражение, так и метки должны иметь значения целого типа (включая тип char).

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

Если в программе не требуется выполнять действия, указанные для последующих меток, прервать выполнение оператора switch можно с помощью оператора break. Оператор break прерывает выполнение оператора switch и передает управление следующему после switch оператору.

Ввести номер месяца и вывести номер квартала, к которому относится введенный месяц.

#include int main ().

{.

int m;

scant («%d», &m); switch (m).

{.

case 1: case 2:

case 3: // номер месяца равен 1, 2 или 3.

printf («1 kvartal»);

break; // выводится сообщение «1 квартал» ,.

//выполнение опратора switch прерывается.

case 4: case 5: case б: printf{ break; case 7: case 8: case 9: printf{ break case 10 case 11 case 12 printf (break;

  • 2 kvartal")
  • 3 kvartal"
  • 4 kvartal");

default: // введен неверный номер месяца, // вывод сообщения об ошибке print f («error»); break;

}.

}.

Структура цикла с заранее известным числом повторений.

Рис. 5.6. Структура цикла с заранее известным числом повторений.

  • • проверка условия повторения (значение счетчика сравнивается с конечным значением);
  • • приращение счетчика (изменение значения счетчика при каждом прохождении тела цикла).

Тело цикла повторяется, пока условие повторения цикла истинно. В качестве тела цикла может выступать один оператор или блок операторов.

Синтаксис цикла for:

for ([]; [];[]) оператор;

Выражение 1 задает инициализацию счетчика и выполняется один раз в начале цикла. Это выражение может быть пустым.

Выражение2 проверяет условие продолжения цикла. Вычисление этого выражения производится в начале каждой итерации и, если его значение равно TRUE, итерация выполняется, иначе цикл заканчивается. Если это выражение равно FALSE в самом начале цикла, тело цикла нс будет выполнено ни разу. Выражение может быть пустым, тогда его значение равно TRUE. В этом случае цикл может быть бесконечным. Например:

#include.

int main ().

{.

int i, j ;

for (i = 1;; i + +).

условие выполнения цикла является пустым, следовательно, оно всегда выполняется */.

j = i;

return 0;

}.

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

В языке С переменная-счетчик может быть изменена в теле цикла. Это может оказывать влияние на длительность цикла. Например:

{.

int i, j ;

for (i = 0; i< 7; i++).

{.

/* в каждой итерации переменная цикла увеличивается на 2, в конце каждой итерации — еще на 1. Таким образом, цикл выполнится 3 раза */ i + = 2 ;

j = i; // j примет значения 2, 5 и 8.

printf («%d «, j);

}.

return 0;

}.

В качестве выражения1 и выраженияЗ могут использоваться сложные выражения, созданные с использованием операции «,».

Пример 5.4.8

С клавиатуры ввести п чисел. Количество чисел п вводится вначале. Найти и вывести сумму введенных чисел.

#include int main{).

{.

int s, i, x, n;

s = 0; // s — сумма введенных чисел, изначально равна 0.

scanf («%d», &n); // ввод количества чисел.

for (i = 0; i.

// меняется от 0 до п-1.

{.

scanf («%d», &х); // ввод очередного числа.

s+=x; // добавление введенного числа к сумме.

}.

printf («%d», s); // вывод накопленной суммы чисел.

return 0;

}.

Пример 5.4.9

С клавиатуры ввести п чисел. Найти и вывести максимальное из введенных чисел.

#include int main{).

{.

int n, i, x; int max;

scanf («%d», &n); // ввод количества чисел.

scanf («%d», &x); // ввод первого числа.

max = x; // первое число принимается за максимум.

for (i = l; i.

{ scanf («%d», &x); // ввод очередного числа.

if (x>max) // если очередное число больше максимума, // максимум меняется шах = х;

}.

printf («%d», max); return 0;

Пример 5.4.10

Два поезда двигаются в одном направлении из пунктов, расстояние между которыми s километров. Скорость первого поезда — vl км/ч, скорость второго поезда — v2 км/ч, v2 > vl. Через сколько часов второй поезд догонит первый?

#include int main ().

{.

int i, j, t = 0; int vl, v2, s;

scanf («%d %d %d», &s, &vl, &v2);

/* Инициализация счетчиков включает две переменные, начальная разность между значениями которых равна s.

При каждом выполнении счетчики увеличиваются на vl и v2. Соответственно, цикл выполняется до тех пор, пока значение первого счетчика больше значения второго. */ for (i = 0, j = -s; i>j; i += vl, j += v2) t + +;

printf («%d», t); return 0;

_}_.

Цикл с предусловием while (рис. 5.7) выполняется, пока указанное в нем условие является истинным. Синтаксис:

while () ;

Структура цикла с предусловием.

Рис. 5.7. Структура цикла с предусловием.

Условие проверяется в начале цикла. Если оно равно TRUE, то выполняется идущий за ним оператор (блок операторов), после чего условие проверяется снова. Если условие ложно, цикл while заканчивается. Если условие ложно в самом начале, то цикл не выполнится ни одного раза.

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

Пример 5.4.11.

С клавиатуры вводится ряд чисел. Признаком окончания ввода является ввод числа, равного нулю. Найти и вывести среднее арифметическое введенных чисел.

#include int main ().

{.

int x, i; float sr;

sr=0; // сумма чисел.

i=0; // количество чисел.

scanf («%d», &x); // ввод очередного числа.

while (x≠0) // пока число не равно нулю.

{.

sr+=x; // увеличение суммы чисел.

i++; // увеличение количества чисел.

scanf («%d», &х); // ввод нового числа.

}.

if (i≠0) // если количество чисел не равно О.

printf («%f», sr/i); // вывод среднего.

// арифметического.

else.

printf («no numbers»); // вывод сообщения.

// об отсутствии чисел.

return 0;

}.

Пример 5.4.12.

С клавиатуры ввести целое число. Найти количество цифр этого числа.

ttinclude int main ().

{.

int n, m=0; // m — количество цифр числа, изначально равна 0.

scanf («%d» / &n); // ввод исходного числа while (п > 0) // пока число больше 0.

{.

т++; // количество цифр в числе увеличивается на 1.

п /= 10; // новое число получается путем деления.

// текущего числа на 10.

}.

printf («%d», m); return 0;

Цикл с постусловием do while (рис. 5.8) повторяет действие, пока условие остается истинным, причем при первой итерации условие не проверяется. Таким образом, этот цикл обязательно выполнится хотя бы один раз. Синтаксис:

do.

;

while ();

В отличие от цикла while, проверка условия выполнения цикла здесь производится в конце, а не в начале каждой итерации. В остальном работа циклов идентична.

Структура цикла с постусловием.

Рис. 5.8. Структура цикла с постусловием.

Пример 5.4.13.

Решение задачи 5.4.11 с помощью оператора do while:

#include int main ().

{.

int i = 0; float x, s = 0; do {.

scant («%d», &x); s += x;

i++;

}.

while (x ≠ 0);

// количество чисел на 1 меньше i, так как при вводе 0 // количество чисел все равно увеличивается printf («%f «, з/ (i — 1)); return 0;

_)_.

Все циклические конструкции могут быть вложенными. Тело цикла среди прочих операторов может включать и операторы цикла.

Пример 5.4.14.

С клавиатуры ввести п целых чисел. Найти и вывести число, имеющее максимальное количество целочисленных делителей. Если таких чисел несколько, вывести первое из них.

{.

/In— количество чисел, x — текущее число,.

//у — число с максимальным количеством делителей int п, х, у;

// к — количество делителей каждого числа,.

// шах — максимальное количество делителей.

int k, max;

int i, j; // i и j — счетчики циклов scant («%d», &n); max = 0;

for (i = 0; i.

// внешний цикл перебирает все числа {.

scanf («%d», &х); k = 1;

// внутренний цикл считает количество делителей // каждого числа for (j = 1; j < х / 2 + 1; j++) if (x%j == 0) k++;

if (k > max).

{.

max = k;

У = x;

} }.

printf («%d», у); return 0;

Пример 5.4.15

С клавиатуры ввести n целых чисел. Найти и вывести число с минимальной суммой цифр. Если таких чисел несколько, вывести последнее из них.

#include int main ().

{.

int n, x, y, z; // n — количество чисел, x — текущее // число, у — число с минимальной // суммой цифр, z — буферная переменная int s, m; // s — сумма цифр числа,.

I/ т — минимальная сумма int i; // i — счетчик цикла.

m = 10 000 000; // изначально минимуму присваивается.

// заведомо невозможно большое значение scanf («%d», &n);

for (i = 1; i <= n; i + +) // внешний цикл перебирает.

// все числа.

{.

scanf («%d», &x);

z = x;

s = 0 ;

while (x ≠ 0) // внутренний цикл вычисляет сумму.

// цифр каждого числа.

{.

s += х % 10; х /= 10;

}.

if (s <= m) { m = s; у = z; }.

}.

printf («%d», y);

}_.

В языке С имеются операторы, позволяющие управлять выполнением итераций внутри тела цикла. К ним относятся следующие операторы:

  • break полностью прерывает выполнение цикла и передает управление следующему за циклом оператору; кроме того, оператор break используется в теле оператора switch-case для разделения выполняемых блоков, о чем говорилось выше;
  • continue прерывает выполнение текущей итерации цикла и передает управление на начало следующей итерации.

Пример 5.4.16

Подсчитать средний балл студентов, сдавших экзамен. При вводе оценки, меньшей 2 или большей 5, считать, что при подведении итогов экзамена допущена ошибка, и прервать обработку. Оценки, равные 2, игнорировать.

#include int main ().

{.

int n; // n — количество студентов,.

// ball — текущая оценка, s — сумма оценок,.

// k — количество студентов, сдавших экзамен int ball, s=0, k=0;

int i, j=0; // i — счетчик цикла, j — признак // прерывания цикла scanf («%d», &n) ;

for (i = 1; i <= n; i + +).

{.

scanf («%d», fcball);

// если оценка больше 5 или меньше 2, выдается // сообщение об ошибке, и цикл прерывается if ({ball >5) II (ball < 2)).

{.

print f («input error»);

j = l;

break;

}.

// оценка, равная 2, игнорируется, происходит // переход к обработке следующей оценки if (ball == 2) continue; s += ball; k++;

}.

if (j==0).

// если цикл не прерывался, выводится результат printf («%f» ,{float)s/k);

return 0;

_2_.

Оператор return осуществляет передачу управления из внутренней функции во внешнюю. Более подробно работа этого оператора будет рассмотрена ниже.

Часть действий по обработке данных в программе может быть выполнена на этапе предварительной обработки перед стадией компиляции. Для этого служат директивы препроцессора (прекомпилятора).

Директива препроцессора — это строка, начинающаяся с символа # и заканчивающаяся символом конца строки. Обычно директивы препроцессора выполняют подстановку, замену или удаление участка текста программы перед ее компиляцией.

Директива #include производит подстановку содержимого указанного файла в то место модуля, где эта директива записана. Директива может быть записана в двух формах:

  • • #include < — подключение заголовочного файла; указанный файл берется из каталога, в котором хранятся заголовочные файлы стандартных библиотек;
  • • #include " файл. Ь" — подключение заголовка; указанный файл берется из текущего каталога, а если он там отсутствует, то из каталога заголовочных файлов стандартных библиотек.

При задании имени файла можно указывать относительный и абсолютный путь к нему.

Директива ttdefine определяет макрос. Она позволяет связать указанный идентификатор (замещаемую часть) с последовательностью лексем (замещающей частью). В результате все вхождения данного идентификатора, встречающиеся после этой директивы, будут заменены на указанные лексемы. Директива может быть записана в двух формах: простого макроса и макроса с параметрами.

Синтаксис простого макроса:

#define.

Идентификатор макроса в тексте программы заменяется последовательностью лексем. Например:

tdefine max_kart 100 //заменяет max_kart на 100.

Синтаксис макроса с параметрами:

#define («формальные параметры>).

В программе такой макрос вызывается с помощью оператора: («фактические параметры;») ;

При вызове макроса происходят две замены. Сначала идентификатор макроса в исходном тексте программы заменяется последовательностью лексем, а затем формальные параметры в теле макроса заменяются значениями фактических параметров оператора вызова макроса.

С помощью такой формы макроса можно записывать простейшие функции, которые не будут компилироваться отдельно, а будут подставлены непосредственно в текст программы на месте их вызова. Например:

#include.

#define max (x, у) (x > у? x: у) int main ().

{.

int x, y; scanf («%d», &x); scant («%d», &y); printf («%d», max (x, y)); return 0;

}.

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

В директиве #define замещающая часть может отсутствовать. Например:

tdefine VALUE1.

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

Директива ttundef отменяет определение макроса. Например:

#undef max_kart // разрывает связь между max_kart и 100.

Все вхождения идентификатора max_kart, встречающиеся после этой директивы, на 100 заменяться не будут. Более того, после директивы #undef идентификатор max kart с помощью новой директивы #dcfine может быть связан с другим значением, и все его дальнейшие вхождения будут заменяться новым значением.

Директивы условной компиляции вызывают обработку частей программы препроцессором в зависимости от условий. К этим директивам относятся #if, #ifdef, Uifndef, #else, ttelif, #endif.

Директива #ifdef обрабатывает часть программы, если идентификатор, указанный в директиве, определен ранее в программе с помощью директивы #define. В противном случае эта часть программы будет удалена. Действие директивы #ifdef распространяется па часть программы до директивы #else, а при ее отсутствии до директивы #endif.

Общий синтаксис директивы:

#if () // если идентификатор! объявлен, {…;} //то сохраняется эта часть.

// программы.

[#elif () // если идентификатор!

//не объявлен,.

// а идентификатор2 объявлен, {…;}] // то выполняется эта часть.

// программы.

[#else {…;}] // если ни один из идентификаторов.

// не объявлен, то выполняется // эта часть программы.

#endif.

Например:

#define INTEGERS.

#ifdef INTEGERS // идентификатор INTEGERS объявлен,.

int i, j; // поэтому переменные i и j имеют тип int.

#else // если бы идентификатор INTEGERS.

// не был объявлен,.

double i, j; // то переменные i и j имели бы // тип double.

#endif.

Действия, выполняемые директивой #ifndef, полностью противоположны действиям директиве #ifdef. Эта директива сохраняет последующий код, если идентификатор, следующий за пей, не был объявлен, и удаляет, если был объявлен. Синтаксис и применение этой директивы полностью аналогичны директиве #ifdef.

Показать весь текст
Заполнить форму текущей работой