Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Козак Н.В. Лекции Основы создания программ в Си...doc
Скачиваний:
24
Добавлен:
23.09.2019
Размер:
2.24 Mб
Скачать

Управляющие конструкции с

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

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

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

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

  • Структура повторения — текущий оператор исполняется снова и снова до тех пор, пока не будет удовлетворено некоторое условие завершения.

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

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

Графическое представление оператора показано на Рис. 2

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

Условный оператор реализует структуру выбора. Он имеет такой вид:

if (условие)

оператор1

else

оператор2

Если условие оценивается как истинное (ненулевое), выполняется oпepaтop1, если как ложное (нулевое), выполняется oпepaтop2. Простейший пример:

if (а > Ь)

max_ab = a;

else

{

max_ab = b;

a += 1;

}

Вместо одиночного оператора всегда можно подставить блок из нескольких операторов, заключенный в фигурные скобки. Ключевое слово else и его операторы могут отсутствовать.

В соответствии с правилом суперпозиции можно строить вложенные структуры if - else, например:

if (a > Ь)

if (a > с)

max_abc = а;

else

max_abc = с;

else ,

if (b > с)

max_abc = b;

else

max_abc = с;

Эта конструкция определяет наибольшее из трех чисел. Если убрать else в первом вложении If то конструкция может работать не так как надо пользователю…Чтоб этого избежать возможно использование фигурных скобок.

Условие в операторе if

Условие оператора if может быть сколь угодно сложным выражением, которое возвращает ненулевой целый результат. Например:

if(x)

doSomething (); //Если х не равно нулю,

if(!x)

doAnotherThing(); //Если х равно нулю,

if(b == с)

doAnotherThing(); //Если b равно с.

if(b != с)

doSomething(); //Если b не равно с.

if((key = getch())== 'q') //Сохранить код клавиши в key

doQuit(); // и проверить, равен ли он 'q'

#define ERR_FLAG 0x80 // Если бит ERR_FLAG

if(flags & ERR_FLAG) //переменной flags установлен.

deportError();

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

doSomething(); //Если а лежит между b и с.

Операции отношения (==, !=, <, >= и т.д.) возвращают ненулевой целый результат, если значения операндов удовлетворяют отношению. В большинстве реализаций С это 1, но полагаться на это не стоит. Если отношение не удовлетворяется, результатом операции будет нуль.

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

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

Оператор выбора switch

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

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

{

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

группа_операторов

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

группа_операторов

[default:

группа_операторов]

}

Графическое представление оператора показано на Рис. 3

Рис. 3 Оператор выбора switch

Рассмотрим пример:

key = getche ();

// Прочитать клавишу.

switch (key)

{ // Определение команды...

case 'f ':

case 'F':

printf("\n\"File\" command selected.\n");

break;

case 'm':

case 'M':

printf("\n\"Message\" command selected.\n");

break;

case 'q':

case 'Q':

printf ( "\n\"Quit\" command selected.\n");

printf ("\n Press a key to Exit...");

getch ();

return 0; // Возврат в Windows,

default:

printf("\nlnvalid command!\n");

}

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

Циклы

В языке С структуры многократного повторения реализуются тремя разновидностями операторов цикла. Это циклы while, do...while и for.

Цикл while

Синтаксис имеет вид:

while (условие_продолжения)

{

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

}

Сначала оценивается условие_продолжения. Если оно истинно, выполняется оператор, после чего управление возвращается заголовку цикла, и все повторяется снова.

Рис. 4 Цикл while

Пример:

int key, done = 0;

while (!done)

{

printf("\nEnter command (F, M or Q) : ");

key = getche(); // Прочитать клавишу.

switch (key)

{

case ‘m’:

...

case 'q': case 'Q':

printf("\n\"Quit\" command selected.\n");

done =1; // Завершить цикл.

break;

}

}

Цикл do...while

Этот цикл имеет такой вид:

do

{

операторы

}

while (условие__продолжения) ;

Рис. 5 Цикл do...while

Цикл for

Цикл for, наиболее универсальный из всех циклов языка С, выглядит так:

for ([инициализация]; [условие]; [модификация])

{

операторы

}

Прежде всего выполняется инициализация цикла; секция инициализации может содержать любое выражение. Инициализация производится только один раз перед началом работы цикла.

Оценивается выражение условия. Если оно истинно, выполняется оператор тела цикла; если условие ложно, происходит выход из цикла и управление передается следующему оператору.

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

Простейшей и самой популярной конструкцией на основе цикла for является цикл с управляющей переменной-счетчиком:

int i;

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

doSomething(i);

Альтернатива циклов рекурсия

У структур повторения в ряде ситуаций есть альтернатива. Это рекурсия, заключающаяся в том, что функция вызывает саму себя. Естественно, такой вызов должен быть условным, т.е. обязательно должен наступить такой момент, когда на очередном шаге рекурсивного вызова не происходит. Есть классический пример рекурсии — 'вычисление факториала’:

unsigned int fасt (unsigned int n)

{

if (n)

return n * fact(n - 1);

else

return 1;

)

Не все языки программирования допускают рекурсию. Си — один из тех языков, в которых рекурсия возможна.

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

Это операторы которые позволяют выйти из некоторого цикла досрочно, до выполнения условия его завершения:

  • Оператор break вызывает прерывание ближайшего (самого внутреннего) заключающего его блока switch, while, do. . .while или for. Управление немедленно передается следующему за блоком оператору.

  • Оператор continue воздействует только на блоки циклов. Он передает управление в конец тела цикла, пропуская, таким образом, все следующие за ним операторы блока. Здесь досрочно завершается не сам цикл, а его текущая итерация.

  • Оператор return прерывает выполнение текущей функции и возвращает ее значение в вызывающую программу. Он имеет вид:

return [выражение];

Блоки и локальные переменные

Поскольку при описании управляющих конструкций мы попутно ввели понятие блока, нужно сделать одно уточнение касательно объявлений и области действия локальных переменных. На самом деле локальные переменные могут объявляться не только в начале тела функции, но и в любом другом блоке (if, while и т.д.). Областью действия переменной является блок, в котором она объявлена; она скрывает любую переменную с тем же именем, объявленную вне данного блока. За пределами блока переменная недоступна.