Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык C. Ч4.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
92 Кб
Скачать

Int main(void)

{

int a = 1, b = 1;

int a_post, pre_b;

a_post = a++; // значение a++ во время этапа присваивания

pre_b = ++b; // значение ++b во время этапа присваивания

printf("a a_post b pre_b \n");

printf("%1d %5d %5d %5d\n", a, a_post, b, pre_b);

return 0;

}

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

a a_post b рге_b 2 12 2

Как и было задумано, значения переменных а и b увеличились на единицу. Однако a post содержит значение переменной а перед изменением, а b__рrе — значение переменной b после изменения. Именно в этом заключается отличие между префиксной и постфиксной формами операции инкремента (рис. 5.5):

a_post = а++; // постфиксная форма: переменная а меняется после

// использования ее значения

b_рге= ++b; // префиксная форма: переменная b меняется до использования

// ее значения

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

while (++shoe < 18.5)

Такая проверка условия завершения цикла позволяет получить таблицу значений вплоть до размера 18. Если вы укажете shoe++ вместо ++shoe, то таблица расширится до размера 19, т.к. значение shoe будет увеличиваться после сравнения, а не до него. Конечно, вы могли бы возвратиться к менее элегантной форме:

shoe = shoe + 1;

но тогда никто не поверит, что вы настоящий программист на языке С.

Приоритеты операций

Операции инкремента и декремента имеют очень высокий приоритет; выше по приоритету только скобки. Поэтому х*у++ означает (х) * (у++), но не (х*у) + + , что благоприятно, т.к. последняя конструкция не имеет смысла. Операции инкремента и декремента применяются только к переменным, а само произведение х*у не является модифицируемым значением, хотя его части таковыми являются.

Не путайте приоритеты этих двух операций с порядком их вычисления. Предположим, мы имеем такой код:

у = 2;

n = 3;

nextnum = (у + n++)*6;

Какое значение получит nextnum? Подстановка значений дает следующее:

nextnum = (2 + 3)*6 = 5*6 = 30

Значение переменной n увеличивается до 4 только после ее использования. Приоритет операции говорит о том, что операция ++ применяется только к n, но не к у + n. Он также указывает, когда значение n используется для вычисления выражения, но момент изменения значения n определяется природой операции инкремента.

Когда n++ является частью выражения, можно считать, что это означает “использовать переменную n, а затем увеличить ее значение на единицу”. С другой стороны, ++n означает “увеличить значение переменной п на единицу, а затем использовать ее”.

Выражения и операторы

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

Выражения

Выражение состоит из комбинации операций и операндов. (Вспомните, что операнд — это то, над чем выполняется операция.) Простейшим выражением является отдельный операнд, и он может служить отправной точкой для построения более сложных выражений. Ниже приведено несколько примеров выражений:

4

-6

4 + 21

a*(b + c/d)/20

q = 5*2

х = ++q % 3

q > 3

Как видите, операндами могут быть константы, переменные и их сочетания. Некоторые выражения представляют собой комбинации выражений меньших размеров, называемых подвыражениями. Например, в четвертом примере c/d является подвыражением.

Операторы

Операторы служат основными строительными блоками программы. Программа — это последовательность операторов с необходимыми знаками пунктуации. Оператор представляет собой завершенную инструкцию для компьютера. В языке С операторы распознаются по наличию точки с запятой в конце. Таким образом, код legs = 4 является всего лишь выражением (которое может быть частью другого выражения), но legs = 4; становится оператором.

Простейшим из возможных считается пустой оператор:

; // пустой оператор

Он ничего не делает и является особым случаем инструкции.

Что же в целом формирует завершенную инструкцию? Прежде всего, в С любое выражение трактуется как оператор, если оно дополнено точкой с запятой. (Это называется оператором выражения.) Следовательно, в С не отклоняются строки, подобные показанным ниже:

8;

3 + 4;

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

х = 25;

+ + х;

у = sqrt(х);

Хотя оператор (во всяком случае, осмысленный оператор) — это завершенная инструкция, не все завершенные инструкции являются операторами. Рассмотрим следующий оператор:

х = 6 + (у = 5) ;

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

Оператор присваивания — это “рабочая лошадка” многих программ; он присваивает значение переменной. Данный оператор состоит из имени переменной, за которым следует операция присваивания (=), а за ней — выражение, сопровождаемое точкой с запятой. Обратите внимание, что оператор while в примере содержит в себе оператор присваивания. Оператор присваивания представляет собой пример оператора выражения.

Оператор функции заставляет функцию делать то, для чего она предназначена. В рассматриваемом примере функция printf () вызывается для того, чтобы вывести некоторые результаты. Оператор while имеет три разных части (рис. 5.6). Первой частью является ключевое слово while. Вторая часть — это условие проверки, помещенное в круглые скобки. К третьей части относится оператор, который выполняется, если условие истинно. В цикл включен только один оператор. Им может быть простой оператор, как в рассматриваемом примере (в таком случае фигурные скобки для его обозначения не нужны), либо составной оператор, как в некоторых приведенных выше примерах (в этом случае наличие фигурных скобок обязательно). Составные операторы будут обсуждаться позже.

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

Оператор return завершает выполнение функции.

Составные операторы (блоки)

Составной оператор — это два или большее количество операторов, сгруппированных вместе путем помещения их в фигурные скобки; его также называют блоком. В программе shoes2.с блок используется для того, чтобы позволить оператору while содержать более одного оператора. Сравните следующие фрагменты кода:

/* фрагмент 1 */

index = 0;

while (index++ < 10)

sam = 10 * index + 2;

printf("sam= %d\n", sam);

/* фрагмент 2 */

index = 0;

while (index++ < 10)

{

sam = 10 * index + 2;

printf("sam = %d\n", sam);

}

Внутри фрагмента 1 в цикл while включен только оператор присваивания. В отсутствие фигурных скобок область действия оператора while распространяется от ключевого слова while до следующей точки с запятой. Функция printf () вызывается только один раз — по завершении цикла.

Во фрагменте 2 наличие фигурных скобок гарантирует, что оба оператора являются частью цикла while, а функция printf () вызывается при каждом выполнении цикла. В терминах структуры оператора while весь составной оператор рассматривается как единственный оператор (рис. 5.7).