Смекни!
smekni.com

Затем, если какой-либо операнд имеет тип DOUBLE, то другой

преобразуется к типу DOUBLE, и это будет типом результата.

В противном случае, если какой-либо операнд имеет тип LONG,

то другой операнд преобразуется к типу LONG, и это и будет

типом результата.

В противном случае, если какой-либо операнд имеет тип

UNSIGNED, то другой операнд преобразуется к типу UNSIGNED,

и это будет типом результата.

В противном случае оба операнда будут иметь тип INT, и это

будет типом результата.

15. Выражения

Старшинство операций в выражениях совпадает с порядком

следования основных подразделов настоящего раздела, начиная

с самого высокого уровня старшинства. Так, например, выраже-

ниями, указываемыми в качестве операндов операции +

(п.15.4), Являются выражения, определенные в п.п.15.1-15.3.

Внутри каждого подраздела операции имеет одинаковое старшин-

ство. В каждом подразделе для описываемых там операций ука-

зывается их ассоциативность слева или справа. Старшинство и

ассоциативность всех операций в выражениях резюмируются в

грамматической сводке в п.18.

В противном случае порядок вычислений выражений не опре-

делен. В частности, компилятор считает себя в праве вычис-

лять подвыражения в том порядке, который он находит наиболее

эффективным, даже если эти подвыражения приводят к побочным

эффектам. Порядок, в котором происходят побочные эффекты, не

специфицируется. Выражения, включающие коммутативные и ассо-

циативные операции ( *,+,&,!,^ ), могут быть переупорядочены

произвольным образом даже при наличии круглых скобок; чтобы

вынудить определенный порядок вычислений, в этом случае не-

обходимо использовать явные промежуточные переменные.

· 192 -

При вычислении выражений обработка переполнения и про-

верка при делении являются машинно-зависимыми. Все существу-

ющие реализации языка “C” игнорируют переполнение целых; об-

работка ситуаций при делении на 0 и при всех особых случаях

с плавающими числами меняется от машины к машине и обычно

выполняется с помощью библиотечной функции.

15.1. Первичные выражения

Первичные выражения, включающие ., ->, индексацию и об-

ращения к функциям, группируются слева направо.

Первичное выражение:

идентификатор

константа

строка

(выражение)

первичное-выражение [выражение]

первичное-выражение (список-выражений нео

первичное-L-значение . Идентификатор

первичное-выражение -> идентификатор

список-выражений:

выражение

список-выражений, выражение

Идентификатор является первичным выражением при условии, что

он описан подходящим образом, как это обсуждается ниже. тип

идентификатора определяется его описанием. Если, однако, ти-

пом идентификатора является “массив ...”, то значением выра-

жения, состоящего из этого идентификатора , является указа-

тель на первый объект в этом массиве, а типом выражения бу-

дет “указатель на ...”. Более того, идентификатор массива не

является выражением L-значения. подобным образом идентифика-

тор, который описан как “функция, возвращающая ...”, за иск-

лючением того случая, когда он используется в позиции имени

функции при обращении, преобразуется в “указатель на функ-

цию, которая возвращает ...”.

Константа является первичным выражением. В зависимости

от ее формы типом константы может быть INT, LONG или DOUBLE.

Строка является первичным выражением. Исходным ее типом

является “массив символов”; но следуя тем же самым правилам,

которые приведены выше для идентификаторов, он модифицирует-

ся в “указатель на символы”, и результатом является указа-

тель на первый символ строки. (имеется исключение в некото-

рых инициализаторах; см. П. 16.6.)

Выражение в круглых скобках является первичным выражени-

ем, тип и значение которого идентичны типу и значению этого

выражения без скобок. Наличие круглых скобок не влияет на

то, является ли выражение L-значением или нет.

· 193 -

Первичное выражение, за которым следует выражение в

квадратных скобках, является первичным выражением. Интуитив-

но ясно, что это выражение с индексом. Обычно первичное вы-

ражение имеет тип “указатель на ...”, индексное выражение

имеет тип INT, а типом результата является “...”. Выражение

E1[E2] по определению идентично выражению * ((E1) + (E2)).

Все, что необходимо для понимания этой записи, содержится в

этом разделе; вопросы, связанные с понятием идентификаторов

и операций * и + рассматриваются в п.п. 15.1, 15.2 И 15.4

соответственно; выводы суммируются ниже в п. 22.3.

Обращение к функции является первичным выражением, за

которым следует заключенный в круглые скобки возможно пустой

список выражений, разделенных запятыми, которые и представ-

ляют собой фактические аргументы функции. Первичное выраже-

ние должно быть типа “функция, возвращающая ...”, а резуль-

тат обращения к функции имеет тип “...”. Как указывается ни-

же, ранее не встречавщийся идентификатор, за которым непос-

редственно следует левая круглая скобка, считается описанным

по контексту, как представляющий функцию, возвращающую це-

лое; следовательно чаще всего встречающийся случай функции,

возвращающей целое значение, не нуждается в описании.

Перед обращением любые фактические аргументы типа FLOAT

преобразуются к типу DOUBLE, любые аргументы типа CHAR или

SHORT преобразуются к типу INT, и, как обычно, имена масси-

вов преобразуются в указатели. Никакие другие преобразования

не выполняются автоматически; в частности, не сравнивает ти-

пы фактических аргументов с типами формальных аргументов.

Если преобразование необходимо, используйте явный перевод

типа (CAST); см. П.п. 15.2, 16.7.

При подготовке к вызову функции делается копия каждого

фактического параметра; таким образом, все передачи аргумен-

тов в языке “C” осуществляются строго по значению. функция

может изменять значения своих формальных параметров, но эти

изменения не влияют на значения фактических параметров. С

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

таком условии, что функция может изменять значение объекта,

на который этот указатель указывает. Порядок вычисления ар-

гументов в языке не определен; обратите внимание на то, что

различные компиляторы вычисляют по разному.

Допускаются рекурсивные обращения к любой функции.

Первичное выражение, за которым следует точка и иденти-

фикатор, является выражением. Первое выражение должно быть

L-значением, именующим структуру или объединение, а иденти-

фикатор должен быть именем члена структуры или объединения.

Результатом является L-значение, ссылающееся на поименован-

ный член структуры или объединения.

Первичное выражение, за которым следует стрелка (состав-

ленная из знаков - и >) и идентификатор, является выражени-

ем. первое выражение должно быть указателем на структуру или

объединение, а идентификатор должен именовать член этой

структуры или объединения. Результатом является L-значение,

ссылающееся на поименованный член структуры или объединения,

на который указывает указательное выражение.

Следовательно, выражение E1->MOS является тем же самым,

что и выражение (*E1).MOS. Структуры и объединения рассмат-

риваются в п. 16.5. Приведенные здесь правила использования

структур и объединений не навязываются строго, для того что-

бы иметь возможность обойти механизм типов. См. П. 22.1.

· 194 -

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

Выражение с унарными операциями группируется справо на-

лево.

Унарное-выражение:

· выражение

& L-значение

· выражение

! Выражение

\^ выражение

++ L-значение

· L-значение

L-значение ++

L-значение—

(имя-типа) выражение

SIZEOF выражение

SIZEOF имя-типа

Унарная операция * означает косвенную адресацию: выраже-

ние должно быть указателем, а результатом является L-значе-

ние, ссылающееся на тот объект, на который указывает выраже-

ние. Если типом выражения является “указатель на...”, то ти-

пом результата будет “...”.

Результатом унарной операции & является указатель на

объект, к которому ссылается L-значение. Если L-значение

имеет тип “...”, то типом результата будет “указатель на

...”.

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

ранд, взятый с противоположным знаком. Для величины типа

UNSIGNED результат получается вычитанием ее значения из 2**N

(два в степени N), где N-число битов в INT. Унарной операции

+ (плюс) не существует.

Результатом операции логического отрицания ! Является 1,

если значение ее операнда равно 0, и 0, если значение ее

операнда отлично от нуля. Результат имеет тип INT. Эта опе-

рация применима к любому арифметическому типу или указате-

лям.

Операция \^ дает обратный код, или дополнение до едини-

цы, своего операнда. Выполняются обычные арифметические пре-

образования. Операнд должен быть целочисленного типа.

Объект, на который ссылается операнд L-значения префикс-

ной операции ++, увеличивается. значением является новое

значение операнда, но это не L-значение. Выражение ++х экви-

валентно х+=1. Информацию о преобразованиях смотри в разборе

операции сложения (п. 15.4) и операции присваивания (п.

15.14).

Префиксная операция—аналогична префиксной операции

++, но приводит к уменьшению своего операнда L-значения.

При применении постфиксной операции ++ к L-значению ре-

зультатом является значение объекта, на который ссылается

L-значение. После того, как результат принят к сведению,

объект увеличивается точно таким же образом, как и в случае

префиксной операции ++. Результат имеет тот же тип, что и

выражение L-значения.

· 195 -

При применении постфиксной операции—к L-значению ре-

зультатом является значение объекта, на который ссылается