Н. И. Лобачевского Факультет Вычислительной Математики и Кибернетики Кафедра иисгео Язык программирования Си Курс лекций

Вид материалаКурс лекций

Содержание


4.2. Форматы основных операторов
Подобный материал:
1   ...   11   12   13   14   15   16   17   18   ...   29
^

4.2. Форматы основных операторов


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

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

v = (тип_переменной_v) e;

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

Оператор ветвления, иногда называемый условным, имеет два формата: укороченный – с одной исполнительной веткой, и полный – с двумя альтернативными ветками:

if (условие) S1;

if (условие) S1; else S2;

Действие S1 выполняется в том случае, когда проверяемое условие оказывается справедливым (истинным). Если в качестве условия выступает одна из операций отношения, то определение его истинности сомнения не вызывает. Но в программах на языке Си в качестве условия зачастую используется значение какой-либо переменной или выражения. В этом случае условие считается выполненным, если проверяемое значение отлично от нуля.

Альтернативное действие S2 выполняется в том случае, если проверяемое условие нарушено.

В большинстве случаев исполнительные ветки условного оператора должны содержать несколько операторов языка. Тогда их приходится заключать в фигурные скобки:

if (условие)

{ t1; t2; ...}

else

{ f1; f2;...}

Операторы, заключенные в фигурные скобки, образуют один составной оператор.

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

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

{

case c1: s11; s12; ... ; break;

case c2: s21; s22; ...; break;

..............................................

case ck: sk1; sk2; ...; break;

default: s1; s2; .....

}

Группа операторов s11; s12; ... выполняется в том случае, если вычисленное значение переключающего выражения совпадает с константой c1. Оператор break, завершающий группу, предотвращает переход на выполнение последующих альтернативных действий и приводит к выходу из оператора switch. Если значение переключающего выражения совпадает с константой c2, то выполняется последовательность действий, представленная операторами s21, s22, ... . Если переключающее выражение принимает значение, отличное от предусмотренных констант c1, c2, ..., ck, то выполняется группа операторов по умолчанию – s1, s2, ... . Последняя альтернативная ветвь (default ...) в операторе switch может отсутствовать.

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

for (f1,f2,...; условие; a1,a2,...)

{ тело цикла }

Действия f1, f2,... выполняются перед входом в цикл. После них проверяется условие, в случае истинности которого выполняется тело цикла. После очередного исполнения тела цикла выполняются действия a1, a2, ... и происходит возврат на проверку условия. Как только условие оказывается нарушенным, управление передается оператору, следующему за телом цикла. Это может произойти и при начальном входе в цикл, так что тело цикла может вообще не выполняться. Любая из трех конструкций в заголовке цикла for может отсутствовать. Так, например, с помощью оператора for(;;); можно организовать бесконечный цикл.

В отличие от других алгоритмических языков, где оператор for предусматривает изменение некоторой переменной по закону арифметической прогрессии, Си позволяет организовать цикл с произвольным изменением одной или нескольких переменных. Например:

for(s=0, i=1; i < n; s += a[i], i *= 2);

Этот оператор определяет сумму элементов массива a[1] + a[2] + a[4] + a[8] + ...

В теле любого цикла имеется возможность организовать досрочный выход из цикла с помощью оператора break. Еще одно нарушение логики работы тела цикла вызывается оператором continue. Он организует переход на продолжение цикла, т.е. либо на группу действий a1, a2,... в операторе for, либо на проверку условия выхода из цикла в операторах while и do.

Цикл с предусловием выглядит следующим образом:

while (условие)

{тело цикла}

Тело цикла выполнятся в случае истинности условия и обходится, если условие нарушено. Здесь также возможна ситуация, когда тело цикла ни разу не выполняется. Перед входом в цикл WHILE в первый раз обычно инициализируют одну или несколько переменных для того, чтобы условное выражение имело какоелибо значение. Оператор или группа операторов, составляющих тело цикла, должны, как правило, изменять значения одной или нескольких переменных, входящих в условное выражение, с тем чтобы в конце концов выражение обратилось в нуль и цикл завершился.

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

Пример программы с зацикливанием

main()

{

int i=4;

while (i > 0)

printf(“\n Турбо Си лучший язык”);

}

Цикл WHILE завершается в следующих случаях:
  • обратилось в ложь условное выражение в заголовке цикла;
  • в теле цикла встретился оператор break;
  • в теле цикла встретился оператор return;

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

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

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

Формат оператора цикла с постусловием таков:

do

{тело цикла}

while (условие);

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

Цикл DO WHILE завершается в тех же случаях, что и цикл WHILE.

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

goto m;

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

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

clrscr();

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

int sign(int n)

{

if (x < 0) return –1;

if (x > 0) return 1;

return 0;

}

К числу операторов описания данных условно можно отнести конструкцию подстановки, начинающуюся со служебного слова #define:

#define a1a2...ak b1b2...bn

Ее смысл заключается в том, что перед компиляцией в тексте исходной программы производится замена последовательности символов a1a2...ak на цепочку b1b2...bn. Такая замена может оказаться полезной в двух ситуациях. Во-первых, она позволяет определять константы, значения которых могут варьироваться при компиляции очередного варианта программы. Во-вторых, таким образом могут делаться макроподстановки, напоминающие встроенные внутренние функции с настраиваемыми фрагментами. Например, макроопределение функции, вычисляющей максимум из двух аргументов, может выглядеть следующим образом:

#define max((a),(b)) ((a) > ((b))? (a) : (b)

Казалось бы, что в приведенном примере слишком много скобок. Однако они позволяют подставить вместо аргументов a и b любые выражения. Иногда текст подставляемой функции может оказаться достаточно длинным, не помещающимся в одной строке. Тогда макроопределение можно перенести на следующую строку, поставив в конце символ переноса – обратный слэш ( \ ). В отличие от большинства операторов строки подстановок не завершаются точками с запятой. Исключение может составить макропроцедура, тело которой должно завершаться таким разделителем.

Весьма полезно сопровождать программу комментариями, поясняющими назначение переменных и смысл наиболее сложных фрагментов программы. Borland C допускает два варианта включения комментариев. В первом случае комментарий начинается после двух подряд идущих символов // и продолжается до конца строки. Во втором случае комментарий может быть и многострочным. Его начинает пара символов /* и завершает такая же пара, записанная в обратном порядке – */.