Выбрать главу

Бинарные операции ассоциируются слева направо. В языке Си имеется одна тернарная операция — условная, обозначаемая ?:. Она ассоциируется справа налево.

Преобразования по умолчанию

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

Преобразования по умолчанию осуществляются следующим образом:

1) Все операнды типа float преобразуются к типу double.

2) Только для СП ТС: если один операнд имеет тип long double, то второй операнд также преобразуется к типу long double.

3) Если один операнд имеет тип double, то второй операнд преобразуется к типу double.

4) Если один операнд имеет тип unsigned long, то второй операнд преобразуется к типу unsigned long.

5) Если один операнд имеет тип long, то второй операнд преобразуется к типу long.

6) Если один операнд имеет тип unsigned int, то второй операнд преобразуется к типу unsigned int.

7) Все операнды типов char или short преобразуются к типу int.

8) Все операнды типов unsigned char или unsigned short преобразуются к типу unsigned int.

9) Иначе оба операнда имеют тип int.

Унарные операции
Унарный минус (-)

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

Унарный плюс (+)

Эта операция реализована полностью в СП ТС. В СП MSC версии 5 она реализована только синтаксически. Операция применяется для того, чтобы запретить компилятору языка Си реорганизовывать скобочные выражения.

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

Обычно компиляторы языка Си осуществляют перегруппировку выражений, переупорядочивая операции, обладающие свойством коммутативности (умножение, сложение, поразрядные операции), пытаясь сгенерировать как можно более эффективный код. При этом скобки, ограничивающие операции, не принимаются в расчет. Однако СП ТС не будет реорганизовывать выражения в скобках, если перед скобками записана операция унарного плюса. Это позволяет, в частности, контролировать точность вычислений с плавающей точкой. Например, если а, b, с и f имеют тип float, выражение

f = а *+ (b * с)

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

В СП MSC для гарантии порядка вычислений следует пользоваться вспомогательной переменной, например

t = b * с;

f = а * t

Обратный код (~)

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

Если операнд имеет знаковый бит, то бит знака также участвует в операции обратного кода (инвертируется).

Логическое отрицание (!)

Операция логического отрицания вырабатывает значение 0, если операнд есть ИСТИНА, и значение 1, если операнд есть ЛОЖЬ. Результат имеет тип int. Операнд должен иметь целый или плавающий тип либо быть указателем.

Примеры:

/* пример 1 */

short х = 987;

х = ~х;

/* пример 2 */

unsigned short у = 0xAAAA;

y = ~y;

/* пример 3 */

if(!(x<y))…

В первом примере новое значение х равно -987.

Во втором примере переменной у присваивается новое значение, которое является обратным кодом беззнакового значения OxAAAA, т. е. 0х5555.

В третьем примере, если х больше или равен у, то результат условного выражения в операторе if равен 1 (ИСТИНА). Если х меньше у, то результат равен 0 (ЛОЖЬ).

Адресация "&"

Операция адресации вырабатывает адрес своего операнда. Операндом может быть L-выражение, в т. ч. немодифицируемое (см. раздел 4.2.7). Результат операции адресации является указателем на операнд. Тип результата — указатель на тип операнда.

Операция адресации не может применяться к битовым полям, а также к идентификаторам, объявленным с классом памяти register.