Г лава II . Управляющие структуры 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Г лава II . Управляющие структуры



Г лава II. Управляющие структуры

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

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

Простые управляющие структуры удобно представить в виде блок-схем:

Рис. 3. Блок-схемы управляющих структур программирования:

следования, ветвления и цикла (с предусловием и с постусловием)

Каждая управляющая структура – это отдельная инструкция программы.

 

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

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

Условный оператор if используется для разветвления процесса вычислений на два направления. Формат оператора:  

if (выражение) оператор_1;

[else оператор_2;]

Вначале вычисляется значение выражения, которое может иметь арифметический тип или тип указателя. Если оно не равно нулю, выполняется  оператор_1, иначе – оператор_2. После этого управление передается на оператор, следующий за условным. Ветвь else может отсутствовать.

Примеры:

if (a>b) max=a;   //Полный условный оператор

else max=b;

if (a<0) a=-a; //Сокращенный условный оператор

Условие помещается в скобки обязательно.

Обратите внимание, что перед else ставится точка с запятой.

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

Пример.

if (х>0) { x=-x; a =2*b;}    

else { int i=2; x*=i; a=b/x;}

При использовании блоков (то есть составных операторов с определениями и описаниями) нельзя забывать о локализации определяемых в блоке объектов. Например, следующая конструкция будет ошибочной:

if (j>0) {int i; i=2*j;} else i=-j;

так как переменная i локализована в блоке и не существует вне него.

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

if (a<b && (a>d || a==0)) b++;

else {b*=a; a=0;}

выражение будет истинно в том случае, если выполнится одновременно условие a<b и хотя бы одно из условий в скобках. Если опустить внутренние скобки, будет выполнено сначала логическое И, а потом – ИЛИ.

Пример. Программа, определяющая, является ли год високосным.

Високосным является год, номер которого делится без остатка на 4. При этом если он делится на 100, то год невисокосный, однако если он делится на 400, то он все равно високосный. Например, високосными являются годы 1980 (делится на 4, но не делится на 100) и 2000 (делится на 400), а год 1900 не является високосным.

#include <stdio.h>

void main()

{

int year;

printf("Введите год: ");

scanf("%d", &year);

printf("Год %d - ", year);

if (year%400==0 || (year%4==0 && year%100!=0))

printf("високосный\n");

else

printf("невисокосный\n");

}

Зачастую одно и то же логическое выражение можно построить "с двух сторон" – с отрицанием и без него. Мы использовали условие високосности:

(year%400==0 || (year%4==0 && year%100!=0))

А могли бы взять противоположный вариант – условие невисокосности:

(year%4!=0 || (year%100==0 && year%400!=0))

Часто нам приходится осуществлять выбор более чем из двух вариантов. Мы можем вкладывать условные операторы друг в друга. Например:

if (выражение_1)

if (выражение_2)

оператор_1;

else    // это else относится ко второму if

оператор_2;

else      // а это else - к первому if

оператор_3;

или

if (выражение_1)

оператор_1;

else      // это else относится к первому if

if (выражение_2)

оператор_2;

else    // а это else - ко второму if  

оператор_3;

Пример. Программа нахождения наибольшего из двух целых чисел a и b.

#include <stdio.h>

void main()

{

int a,b;

printf ("Введите первое число\n");

scanf("%d",&a);

printf ("Введите второе число\n");

scanf("%d",&b);

if (a==b)

printf ("Заданные числа равны\n");

else 

if (a>b)

printf ("Первое число больше второго\n");

else

printf ("Второе число больше первого\n");

}

Замечание. Применяйте отступы в строках, чтобы сделать структуру программы более наглядной.

Остановимся на некоторых особенностях использования условного оператора. Если во вложенной последовательности операторов if...else ветвь else опускается, то при этом может возникнуть неоднозначность. В этом случае нужно помнить следующее правило: else всегда соответствует ближайшему предыдущему if, не содержащему else. Например, в операторе

if (n>0)

if (a>b) z=a;

else z=b;

else-часть относится к внутреннему if.

Если требуется отнести else к внешнему if, то необходимо использовать фигурные скобки:

if (n>0)

{

if (a>b) z=a;

}

else z=b;

Оператор switch

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

switch (переключающее выражение)

{

case константное_выражение_1: операторы_1;

case константное_выражение_2: операторы_2;

 ........

case константное_выражение_n: операторы_n;

[default: операторы;]

}

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

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

Выход из переключателя обычно выполняется с помощью операторов break или return.

Пример. Программа, которая в зависимости от номера дня недели выводит его название.

#include <stdio.h>

void main()

{

int c;

printf ("Введите цифру от 1 до 7:\n");

scanf("%d",&c);

printf ("Соответствующий день недели:\n");

switch (c)

{

case 1: printf ("Понедельник - день тяжелый!\n"); break;

case 2: printf ("Вторник!\n"); break;

case 3: printf ("Среда!\n"); break;

case 4: printf ("Четверг!\n"); break;

case 5: printf ("Пятница!\n"); break;

case 6: printf ("Суббота!\n"); break;

case 7: printf ("Воскресенье! Ура!\n"); break;

default: printf ("Это не цифра от 1 до 7\n");

}

}

Пример. Программа, которая в зависимости от порядкового номера месяца (1, 2, …) выводит на экран соответствующее этому месяцу название времени года.

#include <stdio.h>

void main()

{

int n;

printf ("Введите номер месяца:\n");

scanf("%d",&n);

printf ("Время года: ");

switch (n)

{

case 1: case 2: case 12: printf ("зима\n"); break;

case 3: case 4: case 5: printf ("весна\n"); break;

case 6: case 7: case 8: printf ("лето\n"); break;

case 9: case 10: case 11: printf ("осень\n"); break;

default: printf ("Номер месяца введен неверно\n");

}

}

Обратите внимание, что если после метки с двоеточием идет несколько операторов, то их необязательно помещать в блок с помощью скобок { }.

Метки не изменяют последовательности выполнения операторов. Если не предусмотрены переходы или выход из переключателя, то в нем последовательно выполняются все операторы, начиная с той метки, на которую передано управление. Проиллюстрируем указанную особенность на примере.

Пример. Программа, выводящая названия нечетных целых цифр, не меньших заданной.

#include <stdio.h>

void main()

{

int cif;

printf ("Введите любую десятичную цифру:\n");

scanf("%d",&cif);

switch (cif)

{

case 0: case 1: printf ("один, ");

case 2: case 3: printf ("три, ");

case 4: case 5: printf ("пять, ");

case 6: case 7: printf ("семь, ");

case 8: case 9: printf ("девять\n"); break;

default: printf ("Ошибка! Это не цифра!\n");

}

}

Пусть, например, была введена цифра 6. Компьютер "найдет" метку case 6 и выполнит все операторы, идущие за этой меткой:

case 7: printf ("семь, ");

case 8:

case 9: printf ("девять\n"); break;

Таким образом, на экран будет выведено: семь, девять.

Если поместить оператор break после вывода каждой цифры, то программа будет выводить название только одной нечетной цифры.

 

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

 

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

· цикл с параметром (цикл for)

· цикл с предусловием (цикл while)

· цикл с постусловием (цикл do … while)

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

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

Циклы закрываются по "принципу матрешки": первый цикл закрывается последним. Вот так:

while (...)

{   // while-начало

for (...)  

{ // for-начало

} // for-конец

}   // while-конец

Пример. Вывод на экран таблицы чисел

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

1 2 3 4 5

#include <stdio.h>

void main()

{

for (int i=1; i<=4; i++)  // меняется по строкам

{

for (int j=1; j<=5; j++) // меняется по столбцам

printf("%2d", j); // вывод нескольких столбцов

printf("\n");      // переход на следующую строку

}

}

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

 

1

2 2

3 3 3

4 4 4 4

5 5 5 5 5

#include <stdio.h>

void main()

{

for (int i=1; i<=5; i++)      

{

for (int j=1; j<=i; j++) printf("%2d", i);     

printf("\n");          

}

}

Пример. Программа для вывода на экран всех трехзначных чисел, сумма цифр которых равна заданному натуральному числу n .

1-й способ. Без использования вложенных циклов.

#include <stdio.h>

void main()

{

int n,x,a,b,c; // n – введенное число, x – трехзначное число

printf("Введите 1<=n<=27\n");

scanf("%d",&n);

for (x=100; x<=999; x++)

{

a=x/100;  // a – число сотен

b=x/10%10; // b – число десятков

с=x%10;   // c – число единиц

if (a+b+c==n) printf("%4d", x);

}

printf("\n");

}

2-й способ. С использования вложенных циклов.

#include <stdio.h>

void main()

{

int n,a,b,c;

printf("Введите 1<=n<=27\n");

scanf("%d",&n);

for (a=1; a<=9; a++)

for (b=0; b<=9; b++)

for (c=0; c<=9; c++)

   if (a+b+c==n) printf("%4d", a*100+b*10+c);

printf("\n");

}

Пример. Программа для графического изображения делимости чисел от 1 до n (n задается). В каждой строке отображается очередное число и столько плюсов, сколько делителей у этого числа. Например, если задано число 4, на экран будет  выведено:

1+

2++

3++

4+++

#include <stdio.h>

void main()

{

int n,i,d;

printf("Введите натуральное число n\n");

scanf("%d",&n);

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

{

printf("%d",i);

for (d=1; d<=i; d++)

if (i%d==0) printf("+"); 

printf("\n");

}

}

Пример. Программа поиска простых чисел от 2 до 50.

Простым является число, которое делится без остатка только на единицу и само себя.

1-й способ. Для каждого проверяемого числа num (внешний цикл от 2 до 50) вычисляется количество делителей (внутренний цикл от 1 до num). Если количество делителей равно двум, то это число простое, следовательно, оно выводится на экран.

#include <stdio.h>

void main()

{

int k;

for (int num=2; num<=50; num++) // num – проверяемое число

{

k=0;      // k – количество делителей числа

// delit – возможные делители

for (int delit=1; delit<=num; delit++)

if (num%delit==0) k++; 

if (k==2) printf("%3d", num);

}

printf("\n");

}

Результат работы программы:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

Press any key to continue

2- й способ. Для каждого числа num (внешний цикл от 2 до 50) ищется первый делитель, больший 1 (внутренний цикл). Если найденный делитель равен самому числу, то это число простое, следовательно, оно выводится на экран.

#include <stdio.h>

void main()

{

int delit;

for (int num=2; num<=50; num++)    

{

delit=1;

do                 

delit++;

while (num%delit!=0);            

if (delit==num) printf("%3d", num);

}

printf("\n");

}

Данный вариант программы выполняется быстрее, чем предыдущий.

 

Содержание

Глава II. Управляющие структуры.. 1

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

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

6.2. Оператор switch. 5

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

7.1. Цикл с параметром (цикл for) 8

7.2. Цикл с предусловием (цикл while) 12

7.3. Цикл с постусловием (цикл do … while) 15

7.4. Вложенные циклы.. 17

8. Операторы передачи управления. 21

8.1. Оператор прерывания блока break. 21

8.2. Оператор завершения итерации цикла continue. 21

8.3. Оператор прерывания программы exit 22

8.4. Оператор безусловного перехода. 23

 

Г лава II. Управляющие структуры

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

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

Простые управляющие структуры удобно представить в виде блок-схем:

Рис. 3. Блок-схемы управляющих структур программирования:

следования, ветвления и цикла (с предусловием и с постусловием)

Каждая управляющая структура – это отдельная инструкция программы.

 

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

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

Условный оператор if используется для разветвления процесса вычислений на два направления. Формат оператора:  

if (выражение) оператор_1;

[else оператор_2;]

Вначале вычисляется значение выражения, которое может иметь арифметический тип или тип указателя. Если оно не равно нулю, выполняется  оператор_1, иначе – оператор_2. После этого управление передается на оператор, следующий за условным. Ветвь else может отсутствовать.

Примеры:

if (a>b) max=a;   //Полный условный оператор

else max=b;

if (a<0) a=-a; //Сокращенный условный оператор

Условие помещается в скобки обязательно.

Обратите внимание, что перед else ставится точка с запятой.

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

Пример.

if (х>0) { x=-x; a =2*b;}    

else { int i=2; x*=i; a=b/x;}

При использовании блоков (то есть составных операторов с определениями и описаниями) нельзя забывать о локализации определяемых в блоке объектов. Например, следующая конструкция будет ошибочной:

if (j>0) {int i; i=2*j;} else i=-j;

так как переменная i локализована в блоке и не существует вне него.

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

if (a<b && (a>d || a==0)) b++;

else {b*=a; a=0;}

выражение будет истинно в том случае, если выполнится одновременно условие a<b и хотя бы одно из условий в скобках. Если опустить внутренние скобки, будет выполнено сначала логическое И, а потом – ИЛИ.

Пример. Программа, определяющая, является ли год високосным.

Високосным является год, номер которого делится без остатка на 4. При этом если он делится на 100, то год невисокосный, однако если он делится на 400, то он все равно високосный. Например, високосными являются годы 1980 (делится на 4, но не делится на 100) и 2000 (делится на 400), а год 1900 не является високосным.

#include <stdio.h>

void main()

{

int year;

printf("Введите год: ");

scanf("%d", &year);

printf("Год %d - ", year);

if (year%400==0 || (year%4==0 && year%100!=0))

printf("високосный\n");

else

printf("невисокосный\n");

}

Зачастую одно и то же логическое выражение можно построить "с двух сторон" – с отрицанием и без него. Мы использовали условие високосности:

(year%400==0 || (year%4==0 && year%100!=0))

А могли бы взять противоположный вариант – условие невисокосности:

(year%4!=0 || (year%100==0 && year%400!=0))

Часто нам приходится осуществлять выбор более чем из двух вариантов. Мы можем вкладывать условные операторы друг в друга. Например:

if (выражение_1)

if (выражение_2)

оператор_1;

else    // это else относится ко второму if

оператор_2;

else      // а это else - к первому if

оператор_3;

или

if (выражение_1)

оператор_1;

else      // это else относится к первому if

if (выражение_2)

оператор_2;

else    // а это else - ко второму if  

оператор_3;

Пример. Программа нахождения наибольшего из двух целых чисел a и b.

#include <stdio.h>

void main()

{

int a,b;

printf ("Введите первое число\n");

scanf("%d",&a);

printf ("Введите второе число\n");

scanf("%d",&b);

if (a==b)

printf ("Заданные числа равны\n");

else 

if (a>b)

printf ("Первое число больше второго\n");

else

printf ("Второе число больше первого\n");

}

Замечание. Применяйте отступы в строках, чтобы сделать структуру программы более наглядной.

Остановимся на некоторых особенностях использования условного оператора. Если во вложенной последовательности операторов if...else ветвь else опускается, то при этом может возникнуть неоднозначность. В этом случае нужно помнить следующее правило: else всегда соответствует ближайшему предыдущему if, не содержащему else. Например, в операторе

if (n>0)

if (a>b) z=a;

else z=b;

else-часть относится к внутреннему if.

Если требуется отнести else к внешнему if, то необходимо использовать фигурные скобки:

if (n>0)

{

if (a>b) z=a;

}

else z=b;

Оператор switch

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

switch (переключающее выражение)

{

case константное_выражение_1: операторы_1;

case константное_выражение_2: операторы_2;

 ........

case константное_выражение_n: операторы_n;

[default: операторы;]

}

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

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

Выход из переключателя обычно выполняется с помощью операторов break или return.

Пример. Программа, которая в зависимости от номера дня недели выводит его название.

#include <stdio.h>

void main()

{

int c;

printf ("Введите цифру от 1 до 7:\n");

scanf("%d",&c);

printf ("Соответствующий день недели:\n");

switch (c)

{

case 1: printf ("Понедельник - день тяжелый!\n"); break;

case 2: printf ("Вторник!\n"); break;

case 3: printf ("Среда!\n"); break;

case 4: printf ("Четверг!\n"); break;

case 5: printf ("Пятница!\n"); break;

case 6: printf ("Суббота!\n"); break;

case 7: printf ("Воскресенье! Ура!\n"); break;

default: printf ("Это не цифра от 1 до 7\n");

}

}

Пример. Программа, которая в зависимости от порядкового номера месяца (1, 2, …) выводит на экран соответствующее этому месяцу название времени года.

#include <stdio.h>

void main()

{

int n;

printf ("Введите номер месяца:\n");

scanf("%d",&n);

printf ("Время года: ");

switch (n)

{

case 1: case 2: case 12: printf ("зима\n"); break;

case 3: case 4: case 5: printf ("весна\n"); break;

case 6: case 7: case 8: printf ("лето\n"); break;

case 9: case 10: case 11: printf ("осень\n"); break;

default: printf ("Номер месяца введен неверно\n");

}

}

Обратите внимание, что если после метки с двоеточием идет несколько операторов, то их необязательно помещать в блок с помощью скобок { }.

Метки не изменяют последовательности выполнения операторов. Если не предусмотрены переходы или выход из переключателя, то в нем последовательно выполняются все операторы, начиная с той метки, на которую передано управление. Проиллюстрируем указанную особенность на примере.

Пример. Программа, выводящая названия нечетных целых цифр, не меньших заданной.

#include <stdio.h>

void main()

{

int cif;

printf ("Введите любую десятичную цифру:\n");

scanf("%d",&cif);

switch (cif)

{

case 0: case 1: printf ("один, ");

case 2: case 3: printf ("три, ");

case 4: case 5: printf ("пять, ");

case 6: case 7: printf ("семь, ");

case 8: case 9: printf ("девять\n"); break;

default: printf ("Ошибка! Это не цифра!\n");

}

}

Пусть, например, была введена цифра 6. Компьютер "найдет" метку case 6 и выполнит все операторы, идущие за этой меткой:

case 7: printf ("семь, ");

case 8:

case 9: printf ("девять\n"); break;

Таким образом, на экран будет выведено: семь, девять.

Если поместить оператор break после вывода каждой цифры, то программа будет выводить название только одной нечетной цифры.

 

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

 

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

· цикл с параметром (цикл for)

· цикл с предусловием (цикл while)

· цикл с постусловием (цикл do … while)



Поделиться:


Последнее изменение этой страницы: 2021-01-08; просмотров: 91; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.149.233.72 (0.238 с.)