Структура ветвления

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

В языках программирования структура ветвления реализуется условными конструкциями и конструкциями выбора (селективными).

Условные конструкции

в общем случае имеют форму

если выражение то действие1 иначе действие2;

и имеют следующей смысл: если выражение верно то выполняется действие1, иначе выполняется действие2.

Кроме того, используется и усеченная форма условной конструкции

если выражение то действие1;

нет
да
условие
оператор1
оператор 2
оператор3
нет
да
условие
оператор1
оператор3

На блок-схеме ветвление и усеченное ветвление изображаются следующим образом:

 

 

В С оператор if имеет следующую структуру:

if (условие) опрератор1; else оператор2; // полный вариант

if (условие) опрератор1; // сокращенный вариант

 

Условие может быть арифметическим выражением, отношением и логическим выражением. Оно должно записываться в круглых скобках. От его истинности зависит, будет или не будет выполняться действие, задаваемое следующим далее оператором. В операторе if оператор1 выполняется в том случае, если выражение ненулевое (то есть считается истинным), иначе выполняется оператор2 или не выполняются никакие действия, если оператор2 не задан, то есть отсутствует else. В частности, если a целое, то if (a) эквивалентно if (a!= 0).

Операторы и в сокращенном, и в полном вариантах if могут быть как отдельными, так и составными (несколько действий внутри блочного оператора).

Примеры:

  1. Конструкция if. Сокращенный оператор if имеет следующую структуру:

if (выражение_условие) оператор;

 

Приведем пример программки, определяющей, является ли год високосным (делится нацело на 4, на 400, но не делится на 100).

#include<stdio.h>

int main(void)

{

int year;

printf(“Vvedite god: ”);

scanf(“%d”,&year);

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

{

printf(“Вы ввели год %d”, year);

printf(“Он високосный”);

}

return 0;

}

Обратите внимание, что действия, следующие за оператором if записаны в {}. Всегда помните о том, что оператор if может работать только с одним действием. Если же действий несколько, они должны быть оформлены как составной (блочный) оператор, то есть в {}. Если бы этого не было, то второй оператор printf выполнялся бы всегда, а не только в случае истинности условия. (здесь пример на ошибку)

  1. Конструкция if… else

Полная форма оператора if:

if (выражение_условие) оператор1; else оператор2;

 

Вычислим следующее значение:

y=

#include <stdio.h>

int main(void)

{

float x,y=0.0;

printf("\nEnter x: ");

scanf(“%f”,&x);

if ((x>0)||(x<-1)) y=1/x;

else y=x;

printf("\ny=%f",y);

return 0;

}

 

  1. Множественный выбор – конструкция ‘else –if’

Оператор if позволяет выполнять, или не выполнять некоторое действие. Конструкция if…else дает возможность выбрать одно из двух действий. В то же время, очень часто удобно выбирать не одно из двух, а одно из нескольких условий. Для этой цели служит конструкция else-if. Она имеет следующий синтаксис:

if (выражение_условие) оператор;

else

if (выражение_условие) оператор;

else

if (выражение_условие) оператор;

.

.

else оператор;

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

if (выражение_условие)

оператор;

else if (выражение_условие)

оператор;

else if (выражение_условие)

оператор;

else

оператор;

Если ни одно из условий не является истинным, то выполняется последняя “ветка” else. Если ее нет, то никаких действий не выполняется.

Например, определим вводимое пользователем значение. Если оно лежит в интервале от 1 до 3, то значение выводится на экран, иначе выдается сообщение «Неверное значение!»

#include<stdio.h>

#include<conio.h>

int main(void)

{

int x;

clrscr();

printf("Vvedite cifru ot 1 do 3: ");

scanf("%d",&x);

if(x==1)

printf("\n Vash vibor - 1");

else if (x==2)

printf("\n Vash vibor - 2");

else if (x==3)

printf("\n Vash vibor - 3");

else

printf("Nevernyj vvod!");

return 0;

}

 

Пример (для выполнения лабораторных работ)

Классификация введенного с терминала символа

 

  1. Вложенные операторы if

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

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;

 

 

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

#include<stdio.h>

int main(void)

{

int x,y,z,max;

printf("\n Введите x,y,z");

scanf("%d%d%d",&x,&y,&z);

if(x<y))

if (y<z) max=z;

else max=y;

else

if(x<z) max=z;

else max=x;

 

printf("\n max=%d",max);

return 0;

}

 

 

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

cin>>a>>b;

if (a) {c=b/a; cout<<c;}

else cout<<”Ошибка ввода”;

Часто используются в условиях логические операции &&, ||, !. Операции && и || не будут вычислять второй аргумент, если это не нужно. Например, if (p && r) … вначале проверяет, является ли p не нулем, и только, если это так, то проверяет r.

Еслинекоторое действие выполняется при выполнении двух условий желательно записывать их в виде одного выражения.

Можно записать

if (a>0)

if (b>0) c=a*b;

но лучше

if (a>0 && b>0) c=a*b;

В качестве оператора1 и оператора2 (см. синтаксис if) нельзя использовать определения. Однако, как уже сказано, здесь могут быть составные операторы и блоки. Например:

if (x>0) {x=-x; f(x);}

else {int i=2; x*=i; f(x);}

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

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

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

if (x==1)

if (y==1) cout<<”x равно 1 и y равно 1”;

else cout <<”x не равно 1”;

А на самом деле в ветку else попадаем, если ”x равно 1 и y не равно 1”

Исправим ситуацию оформив внутренний условный оператор как блок:

if (x==1)

{if (y==1) cout<<”x равно 1 и y равно 1”;}

else cout <<”x не равно 1”;

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

если (выражение)

{имеет значение1 то действие1,

имеет значение2 то действие2

….

имеет значениеn то действие n

иначе действиеN+1

}

На блок-схеме мультиветление изображается следующим образом:

 

 
выраж
оператор1
оператор2
оператор n
выр=зн1
выр=зн2
выр=знn

 

В С существует конструкция мультиветвления (переключатель) - switch. Синтаксис переключателя:

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

{

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

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

. . .

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

default:оператор;

}

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

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

 

Пример. Напишите программу, которая определяет, какая буква введена пользователем – гласная или согласная.

#include<stdio.h>

#include<conio.h>

 

int main(void)

{

char ch;

clrscr();

printf("Vvedite bukvu: ");

scanf("%c",&ch);

switch (ch)

{

case 'a':

case 'e':

case 'i':

case 'o':

case 'u':printf("\nGlasnaya");break;

default:printf("\nSoglasnaya");break;

}

return 0;

}

 

Пример:

// вывести названия нечетных цифр, не меньших заданной, цифры вводит пользователь

#include <iostream.h>

void main()

{int ic;

cout<<”\n Введите любую десятичную цифру: ”;

cin>>ic;

cout<<’\n’;

switch (ic)

{case 0: case 1: cout<<”один”; // оператор может быть помечен несколькими сase

case 2: case 3: cout<<”три ”;

case 4: case 5: cout<<”пять”;

case 6: case 7: cout<<”семь”;

case 8: case 9: cout<<”девять”;

break; //выход из переключателя

default: cout<<”Ошибка! это не цифра”;

}// конец переключателя

}// конец программы

 

Результат двух выполнений программы:

Введите десятичную цифру: 4

пять, семь, девять

Введите десятичную цифру: Z

Ошибка! это не цифра

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

Резюме. Правила выполнения оператора switch:

1) вычисляется значение выражения В (ключ);

2) это значение сравнивается последовательно с каждым значением метки, стоящей после ключевого слова case;

3) если обнаруживается значение метки, равное значению ключа, то возможны 2 варианта в зависимости от наличия или отсутствия оператора break:

а) если оператора break нет, то выполняются операторы; следующие после данного case, и операторы, стоящие после всех остальных case и после default данного оператора switch, до очередного оператора break;

б) если после оператора или группы операторов данного case стоит оператор break, то после него выполнение оператора switch завершается;

4) в случае если значение ключа не совпало ни с одной меткой case, то возможен один из двух вариантов выполнения в зависимости от наличия или отсутствия default:

а) если default есть (полная форма оператора switch), то выполняются операторы, стоящие после default;

б) если default нет (сокращенная форма оператора switch), не выполняется ни один оператор switch;

5) все метки вариантов одного оператора switch должны быть различны, т. е.каждая из них должна быть только после одного case;

6) на метку вариантов оператора: switch не рекомендуется переходить с помощью оператора goto, хотя это и допустимо.

 

 

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

 

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

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

- подготовка (инициализация параметров цикла);

- выполнение вычислений цикла (тело цикла);

- модификация параметров (которая фактически является частью тела цикла);

- проверка условия окончания (или условия продолжения) цикла.

Порядок выполнения этих этапов может и меняться. Если условие проверяется до выполнения тела цикл, то говорят о цикле с предусловием. Если – после, то о цикле с постусловием. Главное отличие- цикл с постусловием обязательно выполнится хотя бы один раз.

нет
да
условие
оператор
оператор
нет
да
условие
оператор
оператор

На блок-схеме циклы изображаются следующим образом

 

Цикл называется детерминированным, если число повторений цикла заранее определено (число повторений фиксировано). Цикл называется итерационным, если число повторений тела цикла заранее неизвестно, а зависит от значения параметров, участвующих в вычислениях.

В С существует три конструкции цикла.

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

for (инициализация_цикла; выражение_условие; список_выражений)

тело_цикла

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

while (выражение_условие)

тело_цикла;

· цикл с постусловием

do

тело_цикла

while (выражение_условие)

Конструкцию for чаще применяют для организации детерминированных циклов. А конструкции do и while чаще применяют для итерационных циклов. Хотя такое функциональное разделение довольно условно.

Циклы могут быть простые и вложенные. Вложенными могут быть циклы любых типов. Каждый внутренний цикл должен быть полностью вложен во все внешние циклы. Пересечения циклов не допускаются.

Цикл FOR

Итак, for имеет следующий синтаксис:

for (инициализация_цикла; выражение_условие; список_выражений)

тело_цикла

В блоке инициализация_цикла задается начальное значение переменной-счетчику. Счетчик – это специальная переменная, при помощи которой отсчитывается число шагов цикла. Как известно, самый простой способ сделать ровно 10 шагов состоит в том, чтобы идти и считать. По тому же принципу работает и цикл, только он считает не вслух, а использует для этого специальную переменную – счетчик. Блок инициализации выполняется ровно один раз перед началом работы цикла. Параметр выражение_условие служит для проверки условия выхода из цикла. Как правило, этим условием является достижение счетчиком какого-либо значения. Операторы тела цикла выполняются, пока условие истинно (не равно нулю). Параметр список_выражений используется для изменения значения счетчика (как правило это уменьшение или увеличение на 1). Выражения из списка_выражений выполняются после выполнения операторов тела цикла и до следующей проверки выражения_условия. Эти три параметра разделяются между собой точками с запятой. Тело_цикла не может быть описанием, это либо один (может быть и пустой) оператор, который всегда завершается точкой с запятой, либо блок операторов, заключенных в скобки.

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

#include<stdio.h>

int main(void)

{

int count;

printf(“Это”);

for (count=1;count<=6;count++)

printf(“\nпрекрасный”);

printf(“\nмир!”);

}

 

Подробное объяснение работы цикла.

 

В следующем примере на экран выводятся четные числа от 1 до 25:

int num;

printf(“Четные числа от 1 до 25:”);

for (num=2;num<=25;num+=2)

printf(“\n%d”,num);

 

 

Подробное объяснение работы цикла.

Обратите внимание на то, что после оператора for отсутствует точка с запя­той (;). Это объясняется тем, что на самом деле оператор for вместе с телом цик­ла представляют из себя один оператор. Это очень важная деталь, поскольку ес­ли поставить после оператора for точку с запятой, то компилятор воспримет это как отсутствие тела цикла, и результат работы программы будет отличаться от задуманного.

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

Следующий пример с названием CUBE LIST демонстрирует использование не­скольких операторов в теле одного цикла. Программа возводит в куб числа от 1 до 10 и печатает результаты в двух столбцах.

 

#include<stdio.h>

int main(void)

{

int numb;

for (numb=1;numb<=10;numb++)

{

printf("%d",numb);

printf("\t%d\n",numb*numb*numb);

 

}

return 0;

 

}

 

 

 


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

 

#include<stdio.h>

int main(void)

{int i,j,max;

printf(“Vvedite chislo:”);

scanf(“%d”,&max);

for(i=0,j=max; i<=max; i++,j--)

printf(“\n %d+ %d= %d”,i,j,i+j)

return 0;

}

 

Результат:

Vvedite chislo: 5

0+5=5

1+4=5

2+3=5

3+2=5

4+1=5

5+0=5

 

Подробное объяснение работы цикла.

Как уже было сказано, циклы for могут быть вложенными. Рассмотрим пример:

 

#include<stdio.h>

int main(void)

{int i,j,k;

i=0;

 

printf(“Vvedite chislo strok:”);

scanf(“%d”,&i)

printf(“\n”);

 

for(j=0;j<i;j++)

{ printf(“\n”);

 

for(k=0,k<=j; k++)

printf(“*”);

}

return 0;

}

Результат (если введено 5 строк):

*

**

***

****

*****

 

Цикл for может быть записан и без одного, или нескольких параметров. Например – без блока изменения счетчика:

for (num=0;num!=255;)

{

printf(“Vvedite chislo:”);

scanf(“%d”,num)

.

.

}

 

В этом случае производится выполнение цикла до тех пор, пока не будет введено значение переменной num, равное 255.

 

Цикл while

while (выражение_условие)

тело_цикла;

 

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

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

#include<stdio.h>

int main(void)

{ int n=1;

while (n!=0)

{printf(“Введите число”);

scanf(“%d”,&n);}

return 0:

}

 

Внешне цикл while напоминает упрощенный вариант цикла for. Он содержит условие для продолжения цикла, но не содержит ни инициализирующих, ни инкрементирующих выражений. Так же как for, while сначала проверяет условие, и лишь затем выполняет тело цикла. То есть возможна ситуация, в которой тело цикла не выполнится ни разу.

 

До тех пор пока условие продолжения цикла выполняется, исполнение тела цикла продолжается. В примере выше значение выраженияn!= Оистинно до тех пор, пока пользователь не введет ноль.

 

Замечание: Несмотря на отсутствие инициализирующего оператора, нужно инициализировать переменную цикла до начала исполнения тела цикла. Тело цикла должно содержать оператор, изменяющий значение перемен­ной цикла, иначе цикл будет бесконечным. Таким оператором в цикле из при­мера выше является scanf(“%d”,&n)/

Цикл do - while

цикл с постусловием

do

тело_цикла

while (выражение_условие)

 

В цикле while условие продолжения выполнения цикла помещалось в начало цикла. Это означало, что в случае невыполнения условия при первой проверке тело цикла вообще не исполнялось. В некоторых случаях это целесообразно, но возможны и ситуации, когда необходимо выполнить тело цикла хотя бы один раз вне зависимости от истинности проверяемого условия. Для этого следует ис­пользовать цикл do, в котором условие продолжения цикла располагается не пе­ред, а после тела цикла. Цикл do выполняется до тех пор, пока условие не станет ложным.

 

Как и for, while и do while могут быть вложенными. Рассмотрим в качестве примера программу, которая выводит на экран число символов, введенных до нажатия Enter (вложенный do-while). После этого с клавиатуры читается еще один символ. Если этим символом является Y или y, то программа начинает свою работу заново, а в противном случае заканчивает.

#include<stdio.h>

#include<conio.h>

 

int main(void)

{

int x;

char i,ans;

i=' ';

do

{

 

clrscr();

x=0;

ans='y';

printf("\nVvedite posledivatelnost simbolov:");

do

{

i=getchar(); // printf("%c",i);getch();

x++;

}

while (i!='\n');

i=' ';

printf("\nChislo vvedennyx simbolov %d",--x);

printf("\nProdoljit (Y\\N)");

ans=getch();

}

while (ans=='Y'||ans=='y');

 

return 0;

}

 

 

Основная проблема при организации циклов – возможность зацикливания – бесконечное повторение тела цикла.

Зацикливание может возникнуть по двум основным причинам:

1. Неверно задано условие цикла

2. Неверно в теле цикла меняются параметры, участвующие в условии цикла.

Например, - задача посчитать сумму первых n натуральных чисел.

int i=1,sum=0,n;

while (i>n) {sum+=i; i++;}

printf(“%d”,sum);

Вероятнее всего цикл будет бесконечным, так как n – не инициализировано, и может принимать значение 0. Правильное условие (i<n), причем надо инициализировать n;

 

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

 

Кроме конструкций следования, ветвления, мультиветвления и цикла, существует еще один блок конструкций, изменяющих активную точку выполнения программы – конструкции передачи управления. Это операторы безусловного перехода – return,goto,break,continue. Последние два используются только в циклах. Примеры

 

Оператор return. Будет изучаться позднее. Позволяет завершить работу функции. Позволяет также вернуть из функции значение.

 

С структурный язык, но позволяет работать и с такими не структурными элементами, как опреатор goto и метки.

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

goto идентификатор;

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

При использовании goto следует придерживаться 3 строгих правил:

- не входить внутрь любого блока извне;

- не входить внутрь условной конструкции, переключателя, цикла извне;

- не перескакивать через описания, содержащие инициализацию объектов.

Однако в двух случаях использование goto действительно обосновано

- при необходимости выйти из вложенных циклов или переключателей;

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

 

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

 

 

Оператор перехода к следующей итерацииcontinue(применяется только в циклах). С его помощь завершается текущая итерация и начинается проверка условий дальнейшего продолжения цикла. Типичный пример использования continue - подсчитать сумму только положительных элементов одномерного массива.

for (s=0,i=0;i<n;i++)

{

if (x[i]<=0) continue;

s+=x[i];

}

 

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

exit (return_code)

где return_code – это возвращаемое значение. Ноль используется для указания нормального завершения работы программы. Любое другое воспринимается как ошибка.

 

 








Дата добавления: 2017-09-19; просмотров: 2317;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.183 сек.