Вы находитесь на странице: 1из 10

Синтаксис операторов языка С

Операторы задают определенную последовательность действий компилятора, но в


отличие от выражений, являются законченными предложениями языка. Обычно
операторы заканчиваются точкой с запятой. Операторы имеют названия, отражающие их
назначения или осуществляемые действия.
Формат. Один оператор может занимать одну или более строк. Два или большее
количество операторов могут располагаться на одной строке.
Вложенность. Операторы, которые управляют порядком выполнения (if, if – else,
switch, while, do – while, for) могут быть вложены друг в друга.
Метка оператора – может стоять перед любым оператором, чтобы на этот
оператор можно было перейти с помощью оператора goto. Метка состоит из
идентификатора, за которым стоит двоеточие. Областью определения метки является
данная функция.
AB2: x = 2;

Составной оператор (блок) состоит из одного или большего числа операторов


любого типа, заключенных в фигурные скобки {}. После закрывающейся фигурной
скобки не должно быть точки с запятой.
{ x = 1; y = 2;}
Составные операторы и операторы, полученные в результате вложения
(суперпозиции) операторов называются сложными.

Пустой оператор ; используется, когда по синтаксису оператор требуется, а по


смыслу – нет.

Оператор – выражение: a--; fclose(file) – вызов функции;

Оператор присваивания: y=(a*x+b)*x+c; (есть операция присваивания!)

Операторы объявления - в которых объявляются константы, переменные,


заголовки функций и типы данных: int a;

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


В С++ есть четыре оператора, изменяющих естественный порядок выполнения
вычислений:
1. оператор выхода из цикла break;
2. оператор перехода к следующей итерации цикла continue;
3. оператор возврата из функции return.
4. оператор безусловного перехода goto;
Оператор завершения break – прекращает выполнение ближайшего вложенного
внешнего оператора switch, while, do, for.
Управление передается оператору, следующему за заканчиваемым.
Пример
for (i = 0; i++)
if ((a[i]=b[i])==0) break;
Оператор продолжения continue – передает управление в начало ближайшего
внешнего оператора цикла while, do, for, вызывая начало следующей итерации. Этот
оператор по действию противоположен оператору break. Используется только в теле
цикла.
Пример
for (i=0; i++;){
if (a[i]!= 0) continue;
a[i]=b[i];
k++;
}
Оператор возврата return – прекращает выполнение текущей функции и
возвращает управление вызвавшей программе.
return выражение //с передачей значения выражения.
Пример return x + y;
#include <iostream.h>
int sum (int, int);
void main()
{
cout<<sum(4,3);
}
int sum (int a, int b)
{
return (a+b);
}

Оператор перехода goto метка – передает управление на оператор с меткой.


Оператор безусловного перехода goto имеет формат:
goto метка;
Используется для выхода из вложенных управляющих операторов.
Область действия ограничена текущей функцией.
В теле той же функции должна присутствовать ровно одна конструкция вида:
Метка: оператор;
Метка – это обычный идентификатор, область видимости которого является
функцией, в теле которой он задан.
Пример goto ABC;
Использование оператора безусловного перехода оправдано в двух случаях:
1. принудительный выход вниз по тексту программы из нескольких вложенных
циклов или переключателей;
2. переход из нескольких мест функции в одно (например, если перед выходом из
функции всегда необходимо выполнять какие – либо действия).
В остальных случаях для записи любого алгоритма существуют более подходящие
средства, а использование goto приводит только к усложнению структуры программы и
затруднению отладки. Применение goto нарушает принципы структурного и модульного
программирования, по которым все блоки, из которых состоит программа, должны иметь
только один выход и один вход.
В любом случае не следует передавать управление внутрь операторов if, switch и
циклов. Нельзя переходить внутрь блоков, содержащих инициализацию переменных, на
операторы расположенные после нее, поскольку в этом случае инициализация не будет
выполнена:
int k; …
goto Metka; …
{int a = 3, b = 4;
k = a + b;
Metka: int m = k + 1 …
}
После выполнения этого фрагмента программы значения переменной m не
определенно.
Операторы ветвления

Условный оператор if
Условный оператор if используется для разветвления процесса вычислений на два
направления. Формат оператора:
if (выражение) оператор_1; [else оператор_2;]
Сначала вычисляется
выражение, которое может иметь
арифметический тип или тип
указателя. Если оно не равно нулю
(имеет значение true), выполняется
первый оператор, иначе - второй.
После этого управление
передается на оператор,
следующий за условным.

Одна из ветвей может отсутствовать, логичнее опускать вторую ветвь вместе с


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

Примеры:
if (a<0) b=1;
//1
if (a<b && (a>d || a==0))b++; else {b*=a; a=0;}
//2
if (a<b) {if (a<c) m=a; else m=c;} else {if (b<c) m=b; else
m=c;} //3
if (a++) b++;
//4
if (b>a) max =a; else max=a;
//5
В 1 отсутствует ветвь else.
Если требуется проверить несколько условий, их объединяют знаками логических
операций. Например, выражение в 2 будет истинно в том случае, если выполнится
одновременно условие a<b и одно из условий в скобках. Если опустить внутренние
скобки, будет выполнено сначала логическое И, а потом – ИЛИ.
Оператор в 3 вычисляет наименьшее значение из трех переменных. Фигурные
скобки в данном случае не обязательны, так как компилятор относит часть else к
ближайшему if.
4 напоминает о том, что хотя в качестве выражений в операторе if чаще всего
используются операции отношения, это не обязательно.
Конструкции, подобные оператору 5, проще и нагляднее записывать в виде
условной (тернарной) операции (в данном случае:
max = (b>a) ? b : a;
так как получаемые при использовании условной операции выражения более
компактны и ведут к получению более компактного кода.
!!!Распространенная ошибка при записи условных операторов – использование в
выражениях вместо проверки на равенство (==) простого присваивания (=), например,
if(a=1) b=0;.
Синтаксической ошибки нет, так как операция присваивания формирует результат,
который и оценивается на эквивалентность 0. В данном примере присваивание
переменной b будет выполнено независимо от значения переменной а. Поэтому в
выражениях проверки переменной на равенство константе рекомендуется записывать
константу слева от операции сравнения:
if (1==a) b=0;.

!!!Вторая ошибка – неверная запись проверки на принадлежность диапазона.


Например, чтобы проверить условие 0<x<1, нельзя записать его в условном операторе
непосредственно, так как будет выполнено сначала сравнения 0<x, а его результат (true
или false, преобразованное в int) будет сравниваться с 1. Правильный способ записи:
if(0<x && x<1)…

Если какая-либо переменная используется только внутри условного оператора,


рекомендуется объявить ее внутри скобок, например:
if (int i = fun(t)) a -= i; else a += i;
Объявление переменной в тот момент, когда она требуется, то есть когда ей
необходимо присвоить значение, является признаком хорошего стиля и позволяет
избежать случайного использования переменной до ее инициализации. Объявлять внутри
оператора if можно только одну переменную. Область ее видимости начинается с точки
объявления и включает обе ветви оператора.

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

switch (выражение)
{
case константное_выражение_1: [список_операторов_1]
case константное_выражение_2: [список_операторов_2]

case константное_выражение_3: [список_операторов_n]
[default: операторы ]
}
Выполнение оператора начинается с вычисления выражения (оно должно быть
целочисленным), а затем управление передается оператору из списка, помеченного
константным выражением, значение которого совпало с вычисленным. После этого, если
выход из переключателя явно не указан, последовательно выполняются все
остальные ветви. Выход из переключателя обычно выполняется с помощью операторов
break или return.
Все константные выражения должны иметь разные значения, но быть одного и того
же целочисленного типа. Несколько меток могут следовать подряд. Если совпадения не
произошло, выполняется операторы, расположенные после слова default (а при его
отсутствии управление передается следующему за switch оператору). В случае
синтаксической ошибки в слове default сообщение об ошибке не выдается, поскольку
компилятор воспримет это слово как допустимую метку оператора. Опытные
программисты для поиска ошибок часто включают ветку default даже когда учтены
все возможные варианты.
Пример (программа реализует простейший калькулятор на 4 действия):
#include <iostream.h>
int main ()
{
int a, b, res;
char op;
cout << “\nВведите первый операнд:”; cin >> a;
cout << “\nВведите знак операции:” ; cin >> op;
cout << “\nВведите второй операнд:”; cin >> b;
bool f = true;
switch (op)
{
case ‘+’: res = a + b; break;
case ‘-’: res = a – b; break;
case ‘*’: res = a * b; break;
case ‘/’: res = a / b; break;
default: cout <<”\nНеизвестная операция”;
f = false;
}
if (f) cout <<”\nРезультат:” << res;
return 0;
}

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

Цикл представляет собой участок программы, в котором одни и те же действия


реализуются неоднократно над различными значениями одних и тех же переменных
(объектов).

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


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

и имеет вид :
while (выражение) оператор
Выражение определяет условие повторения тела цикла,
представленного простым или составным оператором. Выполнение
оператора начинается с вычисления выражения. Если оно истинно
(не равно false), выполняется оператор цикла. Если при первой
проверке выражение равно false, цикл не выполнится ни разу.
Тип выражения должен быть арифметическим или приводимым к
нему. Выражение вычисляется перед каждой итерацией цикла.
При реализации цикла в его тело обязательно должны быть
включены конструкции, изменяющие логику проверяемого выражения так, чтобы в конце
концов оно стало ложным. Иначе цикл будет бесконечным.
Пример (программа находит все делители целого положительного числа):
#include <iostream.h>
int main()
{
int num;
cout <<"\nвведите число:";
cin >> num;
int half=num/2; // половина числа
int div=2; // кандидат на делитель
while (div<=half)
{
if (!(num % div))
cout << div <<"\n";
div++;
}
return 0;
}
Распространенный прием программирования – организация бесконечного цикла с
заголовком while (true) либо while (1) и принудительным выходом из тела цикла
по выполнению какого-либо условия.
В круглых скобках после ключевого слова while можно вводить описание
переменной. Областью ее действия является цикл:
while (int x =0) {…/* область действия x */ }

Цикл с постусловием (do while)


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

и имеет вид :
do оператор while выражение;
Сначала выполняется простой или составной оператор,
составляющий тело цикла, а затем вычисляется выражение. Если оно
истинно (не равно false), тело цикла выполняется еще раз. Цикл
завершается, когда выражение станет равным false или в теле цикла
будет выполнен какой-либо оператор передачи управления. Тип
выражения должен быть арифметическим или приводимым к нему.

Пример (программа осуществляет проверку ввода ):


#include <iostream.h>
int main ()
{
char answer;
do
{
cout << "\nКупи слоника! ";
сin>> answer;
}
while (answer!='y');
return 0;
}
Цикл с параметром (for)
Цикл с параметром имеет следующий формат:
for (инициализация; выражение; модификация) оператор;
Инициализация используется для объявления и присвоения начальных значений
величинам, используемым в цикле. В этой части можно записать несколько операторов,
разделенных запятой (операцией "последовательное выполнение "), например так:
for (int i =0, j=2;…)
int k,m;
for (k=1, m=0;…)
Областью действия переменных, объявленных в части инициализации цикла,
является цикл. Инициализация выполняется один раз в начале выполнения цикла.
Выражение определяет условие выполнения цикла: если его результат,
приведенный к типу bool, равен true, цикл выполняется. Цикл с параметром реализован
как цикл с предусловием.
Модификации выполняются после каждой итерации цикла и служат обычно для
изменения параметров цикла. В части модификации можно записать несколько
операторов через запятую. Простой или составной оператор представляет собой тело
цикла.
Пример (оператор вычисляющий сумму чисел от 1 до 100)
for (int i= 1 , s=0; s<=100; i++) s+=i;
Любая из частей оператора for может быть опущена (но точки с запятой надо
оставить на своих местах). Если опущено выражение, то считается, что оно постоянно
истинное (true).
Оператор for(;;); представляет собой бесконечный цикл, эквивалентный
оператору while (1)
Любой цикл while может быть приведен к эквивалентному ему циклу for и
наоборот по следующей схеме:
b1;
for (b1;b2;b3) оператор while (b2)
{oператор; b3;}
Пример (программа находит все делители целого положительного числа):
#include <iostream.h>
int main()
{
int num, half, div;
cout <<"\nвведите число:";
cin >> num;
for (half=num/2,div=2; div<=half; div++)
if (!(num % div))
cout << div <<"\n";
return 0;
}

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

Пример 1. Вложенные циклы. Требуется заполнить весь экран символами '#'.


for (i=l; i<=25; i++)
for (k=l; k<=80; k++)
cout<<'#';

В данной программе 25 раз осуществляется вывод по 80 символов.


В программе можно использовать любые комбинации вложенных циклов всех типов:
while, for, do — while, если этого требует логика построения программы.

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


ввода.
for (i=l; i<=10; i++)
{
do cin>>den;
while (den<l||den>31);
cout<<den;
}

В данном примере внешний цикл выполняется 10 раз, а внутренний будет выполняться


до тех пор, пока не будет введено правильное значение.

Пример 3. Распечатка натуральных чисел от 1 до 15 по пяти столбцам.


int main ()
{
int i,j;
for (i=1; i<=3; i++)
{
for (j=1; j<=5; j++)
cout << 3*(j-1)+i << " ";
cout << “\n";
}
}

Результат выполнения программы будет выглядеть как

1 4 7 10 13
2 5 8 11 14
3 б 9 12 15

Индексная переменная i внешнего оператора цикла принимает значения от 1 до 3


включительно. Эта переменная определяет номер строки, в которой отображается число.
Номер столбца определяется индексной переменной j внутреннего оператора цикла. Эта
переменная при каждом фиксированном значении переменной i пробегает значения от 1
до 5. Во внутреннем операторе цикла выполняется всего одна команда
cout << 3*(j-1)+i << " ";,
с помощью которой распечатываются числа в соответствующей строке. Что касается
внешнего оператора цикла, то в рамках каждого цикла выполняется две команды:
внутренний оператор цикла (распечатываются числа в строке) и команда cout <<
“\n"; (для перехода к новой строке).

Следует четко понимать разницу между двумя (или более) вложенными


операторами цикла и одним оператором цикла с несколькими индексными переменными.

int main ()
{
int i,j;
for (i=10,j = 90; i<j; i+=5,j-=10)
cout << i <<” ” << j <<”\n”;
}

Результатом выполнения программы будет два столбца чисел:


10 90
15 80
20 70
25 60
30 50
35 40
Дело в том, что, в отличие от случая вложенных операторов, в данной ситуации обе
индексные переменные i и j изменяются синхронно. Переменная i инициализируется со
значением 10, а переменная j - со значением 90. За каждый цикл значение переменной i
увеличивается на 5, а значение переменной j уменьшается на 10. Значения переменных
выводятся на экран. Процесс продолжается до тех пор, пока значение переменной i
меньше значения переменной j.

Часто встречающиеся ошибки программировании циклов –использование в теле


цикла неинициализированных переменных и неверная запись условия выхода из цикла.
Чтоб избежать ошибок рекомендуется :
 проверить, всем ли переменным, встречающимся в правой части операторов
присваивания в теле цикла, присвоены до этого начальные значения;
 проверить, изменяется ли в цикле хотя бы одна переменная, входящая в условие
выхода из цикла;
 предусмотреть аварийный выход из цикла по достижению некоторого
количества итераций;
 и конечно, не забывать о том, что если в теле цикла требуется выполнить более
одного оператора, нужно заключать их в фигурные скобки.
Операторы цикла взаимозаменяемы. Но можно привести некоторые рекомендации
по выбору наилучшего в каждом конкретном случае.
Оператор do while обычно используют, когда цикл требуется выполнить хотя бы
раз.
Оператором while удобнее пользоваться в случаях, когда число итераций заранее
неизвестно, очевидных параметров цикла нет.
Оператор for предпочтительнее в большинстве остальных случаев (однозначно
для организации циклов со счетчиками). В С++ он является более гибким средством, чем
аналогичные операторы циклов в других языках программирования.

Возможности цикла for


1. Можно применять операцию уменьшения для счета в порядке убывания.
Пример. Требуется вычислить у5. Возможное решение имеет вид:
for ( i=5, r=1; i>=1; i--) r=r*y;
cout<<"r="<<r;
2. При желании можно организовать счет двойками, тройками, десятками и т.д.
Пример. Приращение при счете, отличное от 1.
for ( n=5; n<61; n+=15) cout<<n;
3. Можно в качестве счетчика использовать не только цифры, но и символы.
Пример. Требуется напечатать алфавит. Возможное решение имеет вид:
for ( chr='A'; chr<='Z'; chr++) cout<<chr;
4. Можно задать возрастание значений счетчика не в арифметической, а в
геометрической прогрессии.
Пример. Требуется подсчитать долг. Возможное решение имеет вид:
for ( k=100; k<185; k*=1.1) соut<<"Долг="<<k;
5. В качестве третьего выражения можно использовать любое правильно составленное
выражение. Оно будет вычисляться в конце каждой итерации.
Пример. Использование в качестве счетчика выражения.
for (k=1; z<=196; z=5*k+23 ) cout<<z;
6. Можно пропускать одно или несколько выражений. (При этом нельзя пропускать
символы «точка с запятой».)
Пример. Неполный список выражений в заголовке тела цикла.
for (р=2; p<=202;) p=p+n/k;
7. Первое выражение не обязательно должно инициализировать переменные, оно может
быть любого типа.
Пример. Произвольное первое выражение в заголовке цикла.
for (соut<<"Вводите числа."; р<=30;) cin>>p;
8. Переменные, входящие в выражения спецификации цикла, можно изменять в теле
цикла.
Пример. Изменение управляющих переменных в теле цикла.
delta=0.1;
for (k=l; k<500; k+=delta) if (a>b) delta=0.5;
9. Использование операции «запятая» в спецификации цикла позволяет включать
несколько инициализирующих и корректирующих выражений.
Пример. Использование операции «запятая» в спецификации цикла.
for (i=1, r=1; i<=10; i++, r*=y)
cout<<"y в cтепени "<<i<<"="<<r;
10. Можно проверять любое другое условие, отличное от числа итераций.