Тема 5. Базовые конструкции структурного программирования

 

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

оператор1
оператор2
оператор
выражение
ИСТИНА(1)
ЛОЖЬ (0)
оператор2
оператор1
выражениеи е
ИСТИНА(1)
ЛОЖЬ (0)

 

 


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

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

Операторы ветвления

Условный оператор if

Условный оператор if используется для разветвления процесса вычислений на два направления (см. рис. выше). Предусмотрен также сокращенный вариант этого оператора:

оператор
выражение
ИСТИНА (1)
ЛОЖЬ (0)

 


Формат оператора:

if (логическое выражение)

оператор1

else

оператор2

Формат для сокращенного варианта:

if (логическое выражение)

оператор

 

При этом операторы могут быть как простыми , так и составными. Пример 1: определить максимальное из двух чисел.

int a = 5, b = 10, max;

 
 
 
//вариант 1:

max = a;

if (b > a)

max = b;

//вариант 2:

 
 
 
if (a >= b)

max = a;

else

max = b;

 
 
 
 
 
 
Пример 2: определить максимальное из трех чисел.

int a = 5, b = 10, с = 7, max;

//вариант 1:

if (a >= b && a >= c)

max = a;

if (b >= a && b >= c)

max = b;

if (c >= a && c >= b)

max = c;

//вариант 2:

 
 
 
 
 
if (a >= b && a >= c)

max = a;

else

if (b >= c)

max = b;

else

max = c;

//вариант 3:

if (a >= b)

 
 
 
 
 
 
 
{

if (a >= c)

max = a;

else

max = c;

}

else

{

if (b >= c)

max = b;

else

max = c;

}

Так как конструкция «else max = c;» повторяется 2 раза, то сделаем упрощение:

//вариант 4:

 
 
 
 
 
 
max = c;

if (a >= b)

{

if (a >= c)

max = a;

}

else

if (b >= c)

max = b;

 
 
 
 
 
 
При использовании вложенных операторов if необходимо помнить, что ветвь else всегда относится к ближайшему выше условию if, не имеющему своей ветви else. Если же ветвь else должна относиться к другому условию if, то необходимо использовать фигурные скобки. Например, если убрать фигурные скобки в предыдущем примере, то программа будет работать неверно, т.к. случай, когда a < b, не анализируется и тогда max будет равен c независимо от значения переменной b:

max = c;

if (a >= b)

if (a >= c)

max = a;

else

if (b >= c)

max = b;

 

 
 
 
 
 
//вариант 5 (наиболее компактный):

max = a;

if (b > max)

max = b;

if (c > max)

max = c;

 

 

На практике довольно часто используется конструкция из вложенных друг в друга операторов if, называемая конструкцией else-if, которая имеет следующий формат:

if (логическое выражение1)

оператор1

else if (логическое выражение2)

оператор2

else if (логическое выражение3)

оператор3

. . .

else if (логическое выражениеN)

операторN

else

операторN+1

Эта последовательность операторов if – самый общий способ описания многоступенчатого принятия решения. Логические выражения вычисляются по порядку. Как только встречается выражение со значением ИСТИНА, выполняется соответствующий ему оператор и на этом последовательность проверок завершается.

Последняя else-часть срабатывает, если все предыдущие условия не выполняются. Иногда в последней else-части не требуется производить никаких действий, в этом случае ее можно опустить или использовать для фиксации ошибочной (невозможной) ситуации. Рассмотрим предыдущий пример и перепишем первый вариант решения с использованием конструкции else-if:

 
 
 
 
 
if (a >= b && a >= c)

max = a;

else if (b >= a && b >= c)

max = b;

else

max = c;

Оператор switch

Оператор switch, называемый также переключателем, предназначен для разветвления процесса вычислений на несколько направлений. Формат оператора:

switch (выражение)

{

case константа 1: [оператор 1]

case константа 2: [оператор 2]

case константа 3: [оператор 3]

. . .

case константа N: [оператор N]

[default: оператор N+1]

}

где квадратные скобки означают, что их содержимое может отсутствовать. Операторы могут быть как простыми, так и составными, но фигурные скобки не ставятся.

Структурная схема оператора switch:

оператор 1
оператор N+1
выражение
константа 1
оператор 2
константа 2
оператор N
константа N
. . .
оператор 3
константа 3

 

 


Выполнение оператора начинается с вычисления выражения, которое должно иметь целочисленный тип. Затем начинается последовательный анализ констант и управление передается тому оператору, для которого константа совпадает с вычисленным значением. После этого анализ продолжается далее. Если в итоге ни одного совпадения не произошло, выполняется оператор, расположенный после слова default, а при его отсутствии – ничего не делается. Все константы должны иметь разные значения, но быть одного и того же целочисленного типа. Для немедленного выхода из переключателя необходимо после соответствующего оператора вставить оператор break. Этот оператор рекомендуется ставить после каждого входящего в переключатель оператора. Пример: выведите на экран название дня недели по его номеру.

#include <stdio.h>

void main()

{

int number;

printf(“Введите номер дня недели:\n”);

scanf(“%d”, &number);

switch(number)

{

case 1: printf(“Понедельник”); break;

case 2: printf(“Вторник”); break;

case 3: printf(“Среда”); break;

case 4: printf(“Четверг”); break;

case 5: printf(“Пятница”); break;

case 6: printf(“Суббота”); break;

case 7: printf(“Воскресение”); break;

default: printf(“Ошибка ввода”); break;

}

}

Иногда может понадобиться выполнить один и тот же оператор в разных ветвях case. В этом случае несколько меток case ставятся подряд:

#include <stdio.h>

void main()

{

int number;

printf(“Введите номер дня недели:\n”);

scanf(“%d”, &number);

switch(number)

{

case 1: case 2: case 3: case 4: case 5:

printf(“Учимся”); break;

case 6: case 7:

printf(“Отдыхаем!”); break;

default: printf(“Ошибка ввода”); break;

}

}

Операторы цикла

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

 

оператор
лог. выраж
ИСТИНА (1)
ЛОЖЬ (0)
модификация параметра цикла  
начальные установки  
оператор
лог. выраж
ИСТИНА (1)
ЛОЖЬ (0)
модификация параметра цикла  
начальные установки  

 


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

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

Цикл завершается, если условие его продолжения не выполняется.

Цикл с предусловием while

Формат оператора следующий:

while (логическое выражение)

оператор

 

Если результат вычисления логического выражения есть ИСТИНА, выполняется образующий тело цикла оператор (простой или составной). Эти действия повторяются до тех пор, пока логическое выражение не примет значение ЛОЖЬ, после чего происходит завершение работы цикла и управление передается оператору, непосредственно следующему за оператором цикла.

Логическое выражение вычисляется перед каждой итерацией цикла. Если при первой проверке значением выражения является ЛОЖЬ, цикл не выполнится ни разу.

Пример 1: сумму 10000$ положили в банк под 10% годовых с условием капитализации процентов. Через сколько лет сумма удвоится?

#include <stdio.h>

void main()

{

float sum = 10000;

float sum2 = 2*sum;

int YearCount = 0;

while(sum < sum2)

{

sum += sum*0.1;

YearCount++;

}

printf(“Число лет = %d”, YearCount);

}

Пример 2: найти все делители целого положительного числа.

#include <stdio.h>

void main()

{

int number, half, div;

scanf(“%d”, &number);

half = number/2;

div =2;

while(div <= half)

{

if(number % div == 0)

printf(“%d ”, div);

div++;

}

}