Академический Документы
Профессиональный Документы
Культура Документы
5. Операторы..............................................................................................................................................1
5.1. Виды операторов............................................................................................................................1
5.2. Оператор-выражение......................................................................................................................2
5.3. Условный оператор if.....................................................................................................................4
5.4. Безусловный оператор goto............................................................................................................7
5.5. Оператор выбора switch.................................................................................................................7
5.6. Оператор разрыва break.................................................................................................................9
5.7. Оператор цикла while...................................................................................................................11
5.8. Оператор цикла do while..............................................................................................................13
5.9. Оператор цикла for.......................................................................................................................15
5. 10. Оператор продолжения continue...............................................................................................17
5.11. Общая структура циклов (подведение итогов)..................................................................18
5. Операторы
В разделе 3.2.2. было приведено понятие оператора, т. е. некоторой
конструкции языка, заканчивающейся знаком точка с запятой (;) и являющейся
указанием на выполнение компьютером некоторого действия.
1
Следовательно, составной оператор может включать в себя другие составные
операторы, а блок может включать в себя составные операторы и другие блоки.
<метка>:<тело оператора>;
5.2. Оператор-выражение
Любое выражение будет оператором, если за ним следует знак точка с
запятой. Таким образом, оператор-выражение имеет следующий общий вид записи:
<выражение>;
Как уже отмечалось, любой оператор может иметь метку, и далее при
представлении общих форм записи операторов этот факт специально не
отражается, но всегда подразумевается. Оператор-выражение относится к классу
простых операторов Си. В результате выполнения в программе оператора-
выражения вычисляется значение выражения в соответствии с теми операциями,
которые в нем определены. Чаще всего в выражении имеется одна или несколько
операций присваивания, и тогда оператор-выражение Си имеет тот же смысл, что и
оператор присваивания в других языках программирования. Рассмотрим примеры
фрагментов программ с использованием операторов-выражений.
Пример 5.2.1.
int x,y.z;
x=-3+4*5-6;
y=3+4%5-6;
z=-3*4%-6/5;
2
В результате выполнения этих операторов х примет значение 11, у значение 1,
а z значение 0. В соответствии с приоритетами операций распишем
последовательность действий, используя круглые скобки.
Пример 5.2.2.
int x=2,y,z;
x*=3+2, x*=y=z=4;
В этом примере оператор-выражение содержит выражение с запятой,
состоящее из двух подвыражений. В начале вычисляется первое подвыражение,
затем второе. В результате выполнения оператора-выражения z и у примут
значение 4, а х значение 40.Обратите внимание, что при описании x
инициализируется значением 2. Последовательность действий:
Для 1-го выражения Для 2-го выражения
х=х*(3+2) (z=4)
х=(х*(3+2)) (y=(z=4))
(х=(х*(3+2))) x=(x*(3+2))*(y=(z=4))
x=((x*(3+2))*(y=(z=4)))
(x=((x)*(3+2))*(y=(z=4))))
Пример 5.2.3.
int x=2, y=1, z=0;
x=x&&y||z; //x=1
y=x++-1; //x=2, y=0
z=++x-1; //x=3, z=2
В результате выполнения этого фрагмента х примет значение 3, у примет
значение 0, а z примет значение 2. В результате выполнения первого оператора-
выражения х примет значение 1, так как правая часть операции присваивания
(логическое выражение) будет ИСТИНА, затем после выполнения второго
оператора х примет значение 2, ввиду того что в нем содержится постфиксная
форма операции увеличения х++, и, наконец, при выполнении третьего оператора х
увеличится еще на единицу, ввиду наличия префиксной формы ++х. Значения для
у и для z очевидны и определяются спецификой применения постфиксной и
префиксной операции для х.
==0(ложь)
<выражение>?
!=0(истина)
<оператор>
на оператор
после IF-ELSE
Рис.5.1. Алгоритмическая схема выполнения if(<выражение>) <оператор>
if (d==c) ++d,c+=3;
4
Разница в том , что теперь здесь два оператора: оператор if и оператор-
выражение c+=3. Теперь в случае истинности (d==c) все будет по-прежнему: d
увеличится на единицу и c увеличится на три. Но в случае ложности (d==c) d не
изменится, а с увеличится на 3. Вновь видоизменив этот пример,
if (d==c) {++d;c+=3;}
!=0(истина) ==0(ложь)
<выражение>?
<оператор1> <оператор2>
Наличие точки с запятой после z=a обязательно, т.к. это есть оператор,
входящий в состав оператора if.
5
Такая цепочка вполне допустима, т. к. на месте оператора может быть любой
оператор, в том числе и оператор if в той или иной форме. Однако в такой записи
достаточно сложно разобраться, поэтому перепишем цепочку так, чтобы else
оказалось под соответствующим if:
if (<выр1>) <оператор1>
else if (<выр2>) <оператор2>
else if (<выр3>) <оператор3>
else <оператор4>
Сопоставим последний else с ближайшим if, и это будет новый оператор,
который включает в себя уже образованный. Схематично это отобразится
следующим образом:
if (<выр1>) <оператор1>
else if (<выр3_)
<оператор3> else
<оператор4>
_
ОПЕРАТОР
ОПЕРАТОР
6
else if(kwh<=15000)
st=(5000*0.4)+(5000*0.6)+(15000-kwh)*0.8;
else st=(5000*0.4)+(5000*0.6)+(5000*0.8)+(kwh-15000)*1.2;
Из примера видно, что фрагмент состоит из оператора if-else, для которого
часть else представляет собой другой оператор if-else.
Рассмотрим еще два простых примера, сопоставляя фрагменты программ а) и б).
if ((s[i] == 'с' or s[i] == 'С') and (s[i + 1] == ' ' or s[i + 1] == '\0') and not(0)) {
count++;
7
5.5. Оператор выбора switch
Оператор выбора (переключатель) предназначен для выбора одного варианта
из множества возможных вариантов разветвления программы. В принципе любое
ветвление программы можно организовать цепочкой операторов if-else if-...-else, но
в ряде случаев оказывается более удобным применять оператор выбора switch.
Оператор switch является составным и имеет следующую общую форму записи:
switch (<выражение>)
{
case <конст. выражение 1> : <оператор(ы)1>
case <конст. выражение 2> : <оператор(ы)2>
...
case <конст. выражение N> : <оператор(ы)N>
default : <оператор(ы)>
}
После ключевого слова switch в скобках записывается выражение, результат
выполнения которого обязательно должен иметь тип int. Далее в фигурных
скобках записываются операторы варианта, помеченные префиксами вида: case
<конст.выражение N>:, в которых константное выражение также должно быть
целым, а все префиксы должны быть различными. Один из вариантов может быть
отмечен префиксом default. Наличие варианта default необязательно, но чаще всего
он присутствует в конструкции switch.
Рис.5.3.
z=<выражение>
Алгоритмическая схема
выполнения Да
<выражение>. Значение
Нет Да
<выражение> Есть Default ?_ Z==_конст.выр1_ ? * Z==_конст.выр1_ ?
оператор(ы)
сравнивается с
константными Нет На оператор после switch
выражениями case-префиксов операторов варианта и выполняется i-тый вариант,
для которого эти значения совпадают. После завершения выполнения операторов
выбранного варианта выполняются операторы следующего за ним варианта и т.д.,
до исчерпания всех операторов варианта. Если значение выражения в switch не
совпадает ни с одним вариантом, то либо выполняется оператор варианта по
умолчанию default (если он присутствует), либо не выполняется никакой вариант
(если нет варианта по умолчанию default). На рис.5.3. представлена
алгоритмическая схема выполнения оператора switch.
8
Рассмотрим пример использования оператора switch. Допустим, необходимо
написать фрагмент программы, которая печатает некоторое четверостишие,
начиная с k-той строки:
switch(k)
{
case 1 : printf("У Лукоморья дуб зеленый\n");
case 2 : printf("Златая цепь на дубе том\n");
case 3 : printf("И днем и ночью кот ученый\n");
case 4 : printf("Все ходит по цепи кругом\n");
default: printf("А.С. Пушкин\n");
}
switch(<выражение>)
{
case <конст. выражение 1>:<оператор(ы)1>
[break;]
case <конст. выражение >:<оператор(ы)2>
[break; ]
................
case <конст. выражение N>:<оператор(ы)N>
[break;]
default:<оператор(ы)>
[break;]
}
Операторы break записываются в вариантах по необходимости, и там, где они
есть, выполнение break приводит к передаче управления за пределы
переключателя, т.е. начинает выполняться оператор программы, записанный после
закрывающей фигурной скобки оператора switch. На первый взгляд кажется не
9
нужным записывать оператор break в варианте default. Но дело в том, что в
операторе switch варианты могут быть записаны в любой последовательности и
default может оказаться первым среди операторов вариантов или между ними и
тогда ему необходим break, чтобы не выполнялись последующие варианты. Кроме
того, это полезно в случае отладки программы, когда может понадобиться
добавлять новое case-выражение после варианта default.
Приведем пример использования оператора break в переключателе. Для этого
изменим постановку предыдущей задачи следующим образом: написать фрагмент
программы, печатающей к-ую строку четверостишия (в отличие от предыдущего
случая, когда необходимо было напечатать четверостишие, начиная с к-ой строки).
switch(k)
{
case 1 : printf("У Лукоморья дуб зеленый\n");
break;
case 2 : printf("Златая цепь на дубе том\n");
break;
case 3 : printf("И днем и ночью кот ученый\n");
break;
case 4 : printf("Все ходит по цепи кругом\n");
break;
default: printf("В стихотворении нет строки с таким номером\n");
}
В заключение раздела отметим, что операторы в case-вариантах и default-
варианте могут отсутствовать. Это используется тогда, когда мы желаем получить
одинаковый результат при переходе к разным префиксам. Например, фрагмент
программы:
показывает, что будет напечатано слово компьютер в том случае, если на вход
переключателя поступит буква k независимо от того, строчная или прописная. Если
поступит буква К, то это вызовет выполнение соответствующего варианта, но
поскольку там операторы отсутствуют, то будут выполняться операторы,
расположенные ниже, пока не встретится оператор break. Этот же прием можно
реализовать по-другому, указав два или более case-префикса перед одним
вариантом, например, так: case 'K': case 'k':printf("компьютер\n"); break;
10
5.7. Оператор цикла while
Операторы цикла позволяют организовать многократное выполнение
некоторого участка программы. Оператор цикла while является составным и имеет
следующую форму записи:
while(<выражение>)
<оператор>
Выражение ?
операто
р
12
100
sum= ∑ N /( N +1 . 0)
Например, необходимо вычислить N =1 , однако, если значение
sum превышает 25, то суммирование прекратить, иначе просуммировать все члены
N/(N+1.0):
float sum;
int N;
sum=0;N=1;
while(N<=100)
{
sum+=N/(N+1.0);
if(sum>25.0) break;
N++;
}
Оператор break используется для досрочного завершения циклов всех видов,
которые будут рассмотрены далее: циклов do while и циклов for. В операторе switch
и в операторах цикла оператор break действует идентично, передавая управление
на оператор, записанный после switch или после тела цикла.
do <оператор> while(<выражение>);
оператор
!=0 (истина)
выражение
==0 (ложь)
13
Примеры, приведенные в предыдущем разделе 5.7, перепишем с
использованием оператора do while.
1. Изменение переменной цикла в <выражение>:
int n=1; float y=0;
do
y +=n/(n+5.0);
while (++n<=50);
2. Изменение переменной цикла в <оператор>:
int n=1; float y=0;
do
{
y +=n/(n+5.0);
++n;
} while (n<=50);
3. Внесение <оператор> в состав <выражение>:
int n=1; float y=0;
do
; /* тело цикла - пустой оператор */
while (y +=n/(n+5.0), ++n, n<=50);
4. Вложенные циклы:
int i=1, j;
double y=0;
do
{
j = 1;
do
{
y +=1/(i+sqrt((double)j);
}while (++j<=50);
}while (++i<=100);
5. Прерывание выполнения цикла оператором break; :
float sum;
int N;
sum=0,N=1;
do
{ sum +=N/(N+1.0);
if (sum>25.0) break;
N++;
} while (N<=100);
Таким образом, оператор do while действует точно так же, как и оператор while, за
исключением того, что тело цикла всегда выполняется хотя бы один раз.
for(<инициализирующий опер-р/выр1>;<выр2>;<выр3>)<оператор>
14
В операторе for <выр1> называется инициализирующим выражением и
обычно оно устанавливает начальное значение переменной цикла. Выражение
<выр2> называется проверяющим выражением и определяет условие завершения
цикла. Выражение <выр3> называется корректирующим и обычно определяет шаг
изменения переменной цикла. Выражения в заголовке цикла for отделяются друг от
друга точкой с запятой. Например, фрагмент программы:
float y=0;
for(int n=1; n<=50; ++n) y +=n/(n+5.0);
50
y=∑ n/(n+1)
вычисляет n=1 . Здесь n=1 – инициализирующее выражение, n<=50 –
проверяющее выражение, ++n – корректирующее (отвечающее за итерацию)
выражение. Оператор цикла for работает следующим образом. Вначале
вычисляется инициализирующее выражение <выр1>. Затем, если проверяющее
выражение <выр2> истинно, то выполняется <оператор> . После выполнения
<оператор> выполняется корректирующее выражение и вновь вычисляется
проверяющее выражение, истинность которого влечет за собой повторное
выполнение <оператор>. Если проверяющее выражение имеет значение ложь, то
выполнение оператора for завершается и управление передается на оператор
программы, записанный после оператора for. На месте инициализирующего
выражения может быть записан инициализирующий оператор, например:
char *ptr = getStr();
int i = 0, j =0;
int lo = 0, hi = max, mid = max/2; //м.быть и другой оператор for
Алгоритмическая схема выполнения оператора for представлена на рис 5.6.
15
n=1
нет
N <= 50?
да
y+=n/(n+5.0)
.0)
++n
k=1;
for(n=7; n>0; --n) k *= n;
2.Отсутствует инициализирующее выражение:
k=1,n=7;
for(; n>0; --n) k*=n;
3.Отсутствуют инициализирующие и проверяющие выражения:
k=1,n=7;
for(; ; --n)
if(n <= 0) break;
16
else k *= n;
4.Отсутствуют инициализирующие, проверяющие и корректирующие
выражения:
k=1,n=7;
for(; ;)
if(n <= 0) break;
else {k *= n; --n;}
Во всех этих примерах k=7! вычисляется по схеме k=7*6*5*4*3*2*1. Из
примеров видно, что если отсутствует инициализирующее выражение, то его
необходимо записать до входа в оператор for, а если отсутствует проверяющее и
корректирующее выражения, то их необходимо реализовать в теле цикла for.
Конечно, это справедливо, если мы желаем хотя бы каким-то образом завершить
цикл.
Большая свобода выбора количества и вида выражений, управляющих
работой цикла for, позволяет с помощью этого оператора делать весьма "заумные"
циклы. Однако оператор for становится более наглядным, если все выражения,
управляющие работой цикла, собраны в его заголовке.
continue;
x = 0; [x = 0;]
while( x == 0){ while( x = get_value()){//( (x = get_value()) == 0){
… …
x = get_value(); }
}
18