Вперед Назад Содержание

6. Операторы

6.1 Введение

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

оператор break оператор goto и операторы с метками составной оператор оператор if оператор continue пустой оператор оператор do оператор return оператор expression оператор switch оператор for оператор while
Операторы языка С состоят из ключевых слов, выражений и других операторов. В операторах языка С появляются следующие ключевые слова:

break default for return case do goto switch continue else if while
Выражения в операторах языка С это те выражения, которые рассматривались Главе "Выражения и присвоения". Операторы, которые могут появляться в операторах языка С, это могут быть любые рассматриваемые в данной Главе операторы. операторы, которые формируют компоненту другого оператора называются "телом" вложенного оператора. Часто телом оператора является "составной" оператор: отдельный оператор, состоящий из одного или нескольких операторов.

Составные операторы ограничиваются фигурными скобками ({}). Все другие операторы языка С заканчиваются точкой с запятой (;).

Любой оператор языка С может начинаться с идентифицирующей его метки, которая состоит из имени и двоеточия. Метки операторов распознаются только оператором goto, поэтому рассмотрены вместе с оператором goto в Разделе 6.8.

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

6.2 Оператор break

Синтаксис: break;

Выполнение

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

Для вложенных операторов оператор break прекращает выполнение только оператора do, for, switch или while, в котором он появился. Для передачи управления из вложенной структуры можно использовать оператор return или goto.

Пример

В данном примере обрабатывается массив строк переменной длины, хранимый в lines. Оператор break вызывает выход из внутреннего цикла for после обнаружения ограничительного пустого символа (\0) в каждой строке и его позиция записывается в lengths[i]. Затем управление передается на внешний цикл for. Переменная i увеличивается и процесс продолжается до тех пор, пока i не станет больше или равна LENGTH.

for (i=0; i<LENGTH; i++) { for (j=0; j<WIDTH; j++) { if (lines[i][j]=='\0') { lengths[i]=j; break; } } }

6.3 Составной оператор

Синтаксис: { [объявление] . . . оператор [оператор] . . . }

Выполнение

Составной оператор обычно появляется как тело другого оператора, например, оператора if. При выполнении составного оператора его операторы выполняются в том порядке, в котором они появляются, если не встретится оператор, который явно передает управление в другое место программы. Глава "Объявление" описывает формы и назначения объявлений, которые могут появиться в начале составного оператора.

Подобно другим операторам языка С, любые операторы составного оператора могут иметь метки. Операторы с метками рассматриваются в Разделе 6.8.

Пример

В данном примере, если i больше 0, то последовательно выполняются все операторы составного оператора.

if (i>0) { line[i]=x; x++; i--; }

6.4 Оператор continue

Синтаксис: continue;

Выполнение

Оператор continue передает управление на следующую итерацию оператора do, for или while, в котором он появляется передавая все оставшиеся операторы тела оператора do, for или while. Следующая итерация оператора do, for или while понимается следующим образом:

Пример

В данном примере тело оператора будет выполнено, если i больше 0. Сначала f(i) присваивается x, затем, если x=1, выполняется оператор continue. Остальные операторы тела игнорируются и выполнение переходит в начало цикла на вычисление i-->0.

while (i-->0) { x=f(i); if (x==1) continue; y+=x*x; }

6.5 Оператор do

Синтаксис: do оператор while (выражение);
Выполнение

Тело оператора do выполняется один или несколько раз до тех пор, пока значением выражения не станет "ложь" (0). Выполнение происходит следующим образом:

  1. Выполняется тело оператора.
  2. Вычисляется выражение. Если его значение "ложь", то выполнение оператора do заканчивается и управление передается следующему оператору программы. Если его значение "истина" (ненулевое значение), то процесс повторяется, начиная с шага 1.
Выполнение оператора do может быть прервано выполнением оператора break, goto или return в теле оператора do.

Пример

В данном операторе do независимо от значения x выполняются два оператора, y=f(x); и x--;. Затем вычисляется значение x>0. Если x больше 0, то тело цикла выполняется снова и опять проверяется x>0. Тело оператора выполняется повторно до тех пор, пока x остается больше 0. Выполнение оператора do прекращается, когда значение x становится 0 или отрицательным. Тело цикла выполнится по крайней мере один раз.

do { y=f(x); x--; } while (x>0);

6.6 Оператор-выражение

Синтаксис: выражение;

Выполнение

При выполнении оператора-выражения, выражение вычисляется в соответствии с правилами, приведенными в Главе "Выражения и присвоения".

В языке С присвоения являются выражениями. Значением выражения в этом случае будет присваиваемое значение (иногда называемое "правым значением").

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

Пример 1

В данном примере x присваивается значение y+3.

x=(y+3);

Пример 2

В данном примере увеличивается значение x.

x++;

Пример 3

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

z=f(x)+3;

6.7 Оператор for

Синтаксис: for([начальное-выражение]; [условное-выражение]; [выражение-цикла]) оператор

Выполнение

Тело оператора for может выполниться несколько раз, а может не выполниться ни разу, пока значением необязательного условного-выражения не станет "ложь". Можно использовать необязательные начальное-выражение и выражение-цикла для инициализации и смены значений при выполнении операторов for.

Выполнение оператора for происходит следующим образом:

  1. Вычисляется начальное-выражение, если оно есть.
  2. Вычисляется условное-выражение, если оно есть. Возможны три результата:
Оператор for также прекращает свое выполнение при выполнении в теле оператора оператора break, goto или return.

Пример

В данном примере происходит подсчет количества символов пробела ('\x20') и табуляции ('\t') в массиве символов с именем line, и каждый символ табуляции заменяется пробелом. Сначала i, space и tab инициализируются значением 0. Затем i сравнивается с константой MAX; если i меньше MAX, то выполняется тело оператора. В зависимости от значения line[i] тело оператора if будет выполнено один раз или не выполнено совсем. Затем i увеличивается и снова сравнивается с MAX. Тело оператора будет выполняться повторно до тех пор, пока i остается меньше MAX.

for (i=space=tab=0; i<MAX; i++) { if (line[i]==' ') space++; if (line[i]=='\t') { tab++; line[i]=' '; } }

6.8 Оператор goto и операторы с метками

Синтаксис: goto имя; . . . имя: оператор
Выполнение

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

Метка оператора имеет смысл только для оператора goto. В любом другом контексте оператор с меткой выполняется так, как если бы ее вообще не было.

Имя метки это просто идентификатор. (Правила построения идентификаторов приведены в Разделе 2.4.) Каждая метка оператора должно отличаться от других меток операторов в данной функции.

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

Пример

В данном примере оператор goto передает управление на точку с меткой exit, если появляется ошибка.

if (errorcode > 0) goto exit; . . . exit: return (errorcode);
v

6.9 Оператор if

Синтаксис: if (выражение) оператор 1 [else оператор2]
Выполнение

Тело оператора if выполняется выборочно, в зависимости от значения выражения, по следующей схеме:

  1. Вычисляется значение выражения.
  2. Управление передается от оператора if на следующий оператор программы.
Пример 1

В данном примере если i больше нуля, то выполняется оператор y=x/i. Если i меньше или равно нулю, то значение i присваивается x и y присваивается значение f(x). Обратите внимание на то, что формирующий предложение if оператор заканчивается точкой с запятой.

if (i>0) y=x/i; else { x=i; y=f(x);}
Примечание

В языке С отсутствует оператор "else if", но этого же эффекта можно достигнуть вложенными операторами if. Оператор if может быть вложен либо в предложение if, либо в предложение else другого оператора if.

При вложении операторов if и предложений else следует использовать скобки для группировки операторов и предложений в составные операторы, что проясняет Ваши намерения. Если скобки не задать, то компилятор попытается разрешить конфликт сам, группируя каждый else с наиболее близким к нему if, у которого else отсутствует.

Пример 2

В данном примере предложение else связывается с внутренним оператором if. Если i меньше или равно 0, то никакое значение x не присваивается.

if (i>0) /* без скобок */ if (j>i) x=j; else x=i;
Пример 3

В данном примере сковки окружают внутренний оператор if. В результате этого статья else становится частью внешнего оператора if. Если i меньше или равно 0, то значение i присваивается x.

if (i>0){ /* со скобками */ if (j>i) x=j;} else x=i;

6.10 Пустой оператор

Синтаксис: ;
"Пустой оператор" это оператор, который состоит только из точки с запятой. Он может появиться везде, где ожидается появление оператора. При выполнении пустого оператора ничего не происходит.

Операторы подобные do, for, if и while требуют наличия выполняемого оператора в теле оператора. В данном случае пустой оператор удовлетворяет синтаксическим требованиям, если действительно не нужно иметь выполняемое тело оператора.

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

Пример

В данном примере выражение цикла line[i++]=0 в цикле for инициализирует первые 10 элементов line значением 0. Телом оператора является пустой оператор, т.к. не нужно никаких дополнительных операторов.

for (i=0; i<10; line[i++]=0) ;

6.11 Оператор return

Синтаксис: return [выражение]
Выполнение

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

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

Если в определении функции отсутствует оператор return, то управление автоматически передается на вызов функции после выполнения последнего оператора вызванной функции. При этом не определено возвращаемое вызванной функцией значение. Если от функции не требуется возврат какого-либо значения, то функция объявляется с возвращаемым значением типа void.

Пример

В данном примере функция main вызывает две функции: sq и draw. Функция sq возвращает в функцию main значение x*x, где оно присваивается y. Функция draw не возвращает значение и объявлена типом void. Попытка присвоения возвращаемого функцией draw значения вызовет появление диагностического сообщения.

main() { void draw(int,int); long sq(int); . . . y=sq(x); draw(x, y); . . . } long sq(x) int x; { return (x*x); } void draw(x,y) int x, y; { . . . return; }

6.12 Оператор switch

Синтаксис: switch (выражение) { [объявление] . . . [case постоянное-выражение:] . . . [оператор] . . . [default: [оператор]] }
Выполнение

Оператор switch передает управление на оператор в своем теле. Управление будет передано тому оператору, значение case постоянное-выражение которого совпадает с выражением switch. Оператор switch может содержать любое число элементов case. Выполнение тела оператора начинается в выбранном операторе и заканчивается в конце тела или в тот момент, когда оператор передаст управление вне тела.

Оператор default выполняется в том случае, если ни одно постоянное-выражение case которого не совпадет с выражением switch. Если оператор default не задан и ни одно совпадение с case не обнаружено, то ни один из операторов тела switch не будет выполнен. Располагать оператор default в конце не обязательно, он может появиться в произвольном месте тела оператора switch.

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

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

Примечание

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

Пример 1

В данном примере будут выполнены все три оператора тела switch, если c равно A. При этом управление передается на первый оператор (capa++;) и продолжается до конца тела. Если c равно a, то значения lettera и total увеличиваются. В противном случае будет увеличено только значение total.

switch (c) { case 'A': capa++; case 'a': lettera++; default: total++; }
Пример 2

В данном примере за каждым оператором тела switch следует оператор break. Оператор break форсирует выход из тела оператора после выполнения одного оператора. Если i равно -1, то увеличивается только n. За оператором n++ следует оператор break, что вызывает передачу управления вне тела оператора, в обход оставшихся операторов. Аналогично, если i равно 0, то увеличивается только z; если i равно 1, то увеличивается только p. Финальный оператор break не является обязательным, т.к. управление выйдет из тела составного оператора автоматически по достижении его конца. Он поставлен здесь для единообразия.

switch (i) { case -1: n++; break; case 0: z++; break; case 1: p++; break; }

Использование нескольких меток

На один оператор может указывать несколько меток case, как это показано в следующем примере:

case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : hexcvt(c);
Хотя можно поставить метку на любой оператор тела оператора switch, в качестве носителя метки необязательно должен быть оператор. Можно свободно ставить операторы с метками и без меток. Однако, следует помнить о том, что после того, как оператор switch передаст управление на какой-либо оператор тела, будут выполнены все операторы блока, независимо от того, имеют ли они метки или нет.

6.13 Оператор while

Синтаксис: while (выражение) оператор
Выполнение

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

  1. Вычисляется значение выражения.
  2. Если значение выражения есть "ложь", то тело оператора while не выполняется, и управление передается на следующий за оператором while оператор программы.

    Если значение выражения есть "истина" (не ноль), то выполняется тело оператора и процесс повторяется с шага 1.

Выполнение оператора while также может быть закончено выполнением оператора break, goto или return в теле оператора.

Пример

В данном примере символы string2 копируются в string1. Если i больше или равно 0, то string2[i] присваивается string1[i] и значение i уменьшается. Когда достигнет значения 0 или упадет ниже него, выполнение оператора while заканчивается.

while (i>=0) { string1[i]=string2[i]; i--; }


Вперед Назад Содержание