Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
приблудова рулит.doc
Скачиваний:
39
Добавлен:
27.09.2019
Размер:
403.46 Кб
Скачать

6 Арифметико-логические операции над переменными

Арифметико-логические операции

Приведенные ниже операции упорядочены по убыванию приоритета.

I. Операции с наивысшим приоритетом

1. () вызов функции;

2. [] выбор элемента массива; 7

3. -> косвенный выбор элемента;

4. . прямой выбор элемента.

II. Унарные операции

1. ! логическое отрицание (NOT);

2. ~ побитовая инверсия;

3. – унарный минус;

4. ++ увеличение на единицу;

5. - - уменьшение на единицу;

6. & получение адреса переменной;

7. * получение значения по адресу;

8. sizeof размер операнда в байтах.

III. Мультипликативные

1. * умножение;

2. / деление;

3. % вычисление остатка от деления (для целочисленных операндов).

IV. Аддитивные

1. + бинарный плюс;

2. - бинарный минус.

При равном приоритете бинарные операции группируются слева напра-

во.

V. Сдвиги

1. >> cдвиг вправо;

2. << cдвиг влево.

VI. Сравнения

1. < меньше;

2. <= меньше или равно;

3. > больше;

4. >= больше или равно.

VII. Равенство

1. = = равно;

2. != не равно.

Результатом выражений с данными операциями является истина (ненулевое

значение) или ложь (0).

VIII. Побитовые

1. & побитовое И (AND);

2. ^ побитовое исключающее ИЛИ (XOR);

3. | побитовое ИЛИ (OR).

IX. Логические 8

1. && логическое И (AND);

2. || логическое ИЛИ (OR).

Логические операции служат для связывания выражений, включающих в

себя операции отношения.

Арифметические операции

К четырем обычным арифметическим операциям сложения +, вычитания -, умножения * и деления / в Си добавлена операция нахождения остатка от деления первого целого числа на второе, которая обозначается символом процента %. Приоритет у операции вычисления остатка % такой же, как и у деления или умножения. Отметим, что операция % перестановочна с операцией изменения знака (унарным минусом), например, в результате выполнения двух строк

x = -(5 % 3);

y = (-5) % 3;

обеим переменным x и y присваивается отрицательное значение -2.

Операции увеличения и уменьшения

В Си добавлены операции увеличения и уменьшения на единицу, которые, к примеру, очень удобно применять к счетчикам. Операция увеличения записывается с помощью двух знаков сложения ++, операция уменьшения - с помощью двух минусов --. Например, операция ++, примененная к целочисленной переменной i, увеличивает ее значение на единицу:

++i; эквивалентно i = i+1

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

double x;

. . .

++x; // Ошибка! Операция ++ неприменима

// к вещ. переменной

Операция ++ увеличивает значение переменной на "минимальный атом". Так как для вещественных переменных такого "атомарного" значения нет, операции увеличения и уменьшения для них запрещены.

Для указателей операция ++ увеличивает значение переменной на размер одного элемента того типа, на который ссылается указатель. Для указателя "атомом" является один элемент заданного типа, поэтому размер одного элемента и является шагом изменения значения указателя. Это очень естественно, т.к. после увеличения указатель будет содержать адрес следующего элемента данного типа, а после уменьшения - адрес предыдущего элемента. Пример:

double a[100];

double *p = &(a[15]); // в p записывается адрес

// элемента массива a[15]

++p; // в p будет адрес элемента a[16]

// (адрес увеличивается на sizeof(double) == 8)

Описаны массив a вещественных чисел типа double и указатель p на элементы типа double. При описании указателя p в него заносится начальное значение, равное адресу элемента a[15] массива a. После выполнения операции увеличения ++ в переменной p будет содержаться адрес следующего элемента a[16]. Физически содержимое переменной p увеличивается на размер одного элемента типа double, т.е. на 8.

Операции увеличения ++ и уменьшения -- на единицу имеют префиксную и суффиксную формы. В префиксной форме операция записывается перед переменной, как в приведенных выше примерах. В суффиксной форме операция записывается после переменной:

++x; // Префиксная форма

x--; // Суффиксная форма

Разница между префиксной и суффиксной формами проявляется только при вычислении сложных выражений. Если используется префиксная форма операции ++, то сначала переменная увеличивается, и только после этого ее новое значение используется в выражении. При использовании суффиксной формы значение переменной сначала используется в выражении и только затем увеличивается. Примеры:

int x = 5, y = 5, a, b;

a = (++x) + 2; // переменной a присваивается значение 8

b = (y++) + 2; // переменной b присваивается значение 7

С логической точки зрения, префиксная операция более естественна (при использовании суффиксной формы надо сперва вычислить сложное выражение и только затем вернуться к увеличению переменной, т.е. операция ++ выполняется не в момент ее использования, а как бы откладывается на потом). Забегая вперед, отметим, что это различие весьма существенно при программировании на C++ в случае переопределения операторов увеличения для классов. Тем не менее, в большинстве книг по Си суффиксная форма используется чаще (скорее всего, эта традиция, связаная с эстетикой текста).

Дадим два совета (возможно, не бесспорные) по использованию операций ++ и --:

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

  • double *p, x, y;

  • . . .

  • y = *p++ + x;

лучше использовать фрагмент

double *p, x, y;

. . .

y = *p + x;

++p;

С точки зрения компилятора, они абсолютно эквивалентны, но второй фрагмент проще и понятнее (и, значит, вероятность ошибки программирования меньше);

  • всегда отдавайте предпочтение префиксной форме операций ++ и --. Например, вместо фрагмента

  • int x, y;

  • . . .

  • x++; y--; // Используется суффиксная форма

лучше использовать фрагмент

int x, y;

. . .

++x; --y; // Лучше применять префиксную форму