Здесь определяются синтаксис, порядок вычисления и назначение выражений. Выражение — это последовательность операций и операндов, которая задает вычисление. Вычисление может выдавать в качестве результата значение и может вызывать побочные эффекты.
Порядок вычисления подвыражений определяется приоритетом и порядком применения операций. Обычные математические правила ассоциативности и коммутативности операций действуют только, если операции действительно ассоциативны или коммутативны. За исключением оговоренных случаев порядок вычисления операндов конкретной операции неопределен. В частности, если в выражении значение изменяется дважды, результат выражения неопределен, если только порядок выполнения не обеспечивается самими операциями, например:
i = v[i++]; // значение ‘i’ не определено i=7,i++,i++; // ‘i’ есть 9
Переполнение целых игнорируется. Деление на ноль вызывает ошибку времени выполнения.
Первичные выражения
Первичными выражениями являются литералы имена и выражения в скобках.
первичное-выражение: литерал ( выражение ) идентификатор
Литерал является первичным выражением. Его тип определяется его видом.
Выражение в скобках является первичным выражением, тип и значение которого идентичны им же у выражения без скобок.
Постфиксные выражения
Постфиксные выражения применяются слева направо.
постфиксное-выражение: первичное-выражение постфиксное-выражение [ выражение ] постфиксное-выражение ( список-выражений opt ) имя-простого-типа ( список-выражений opt ) постфиксное-выражение . имя постфиксное-выражение ++ постфиксное-выражение -- список-выражений: выражение-присваивания список-выражений , выражение-присваивания
Индексация
Постфиксное выражение, за которым следует выражение в квадратных скобках, является выражением индексирования. Первое из выражений должно иметь тип массив T, а второе быть целочисленного типа. Тип результата есть T.
Вызов функции является постфиксным выражением, за которым следует (возможно, пустой) список выражений в скобках, разделенных запятой.
Эти выражения образуют фактические параметры функции. Постфиксное выражение должно иметь тип «функция, возвращающая T», а результат операции вызова имеет тип T.
При вызове функции происходит инициализация каждого формального параметра фактическим параметром. Производятся стандартные преобразования типа. В функции может изменяться значения непостоянных формальных параметров, но эти изменения не могут повлиять на значения фактических параметров, кроме того случая, когда формальный параметр имеет тип ссылки. Если формальный параметр имеет тип ссылки, при необходимости может создаваться временная переменная.
Порядок вычислений параметров неопределен. Все побочные эффекты выражений фактических параметров могут происходить перед началом выполнения функции. Порядок вычисления постфиксных выражений и списка выражений параметров неопределен.
Допустимы рекурсивные вызовы.
Доступ к члену класса
Постфиксное выражение, за которым следует точка ( . ) и имя, является постфиксным выражением. Первое выражение должно быть объектом типа класс, а имя должно быть именем члена этого класса. Результатом будет поименованный член объекта, и он будет lvalue, если член является lvalue.
Инкремент и декремент
Значение, получаемое в результате применения постфиксной операции ++, есть значение операнда. Операнд должен быть lvalue.
Тип операнда должен быть арифметический. После выборки результата (для дальнейшего использования) объект увеличивается на 1. Тип результата совпадает с типом операнда, но не является lvalue (см. Операции присваивания и Аддитивные операции ).
Постфиксная операция -- сводится к операции декремента (уменьшение на 1) и аналогична операции ++.
Унарные операции
Выражения с унарными операциями выполняются справа налево.
унарное-выражение: постфиксное-выражение ++ унарное выражение -- унарное выражение унарная-операция: один из + - ! ~
Операнд унарной операции + должен быть арифметического типа и результатом будет значение операнда. Для целочисленных операндов производится стандартное преобразование целочисленных. Тип результата есть тип преобразованного операнда.
Операнд унарной операции - должен иметь арифметический тип и результатом будет изменение знака операнда. Для целочисленных операндов выполняется стандартное преобразование целочисленных. Операция для беззнаковых величин выполняется с помощью вычитания значения операнда из 2**n, где n число битов в представлении преобразованного операнда. Тип результата есть преобразованного операнда.
Операнд операции логического отрицания ! должен иметь арифметический тип, результат равен 1, если значение операнда есть 0, и равен 0, если операнд не равен 0. Тип результата есть int.
Операнд операции ~ должен иметь целочисленный тип, результатом будет обращение двоичного представления операнда. Выполняются стандартные преобразования целочисленных. Тип результата есть тип преобразованного операнда.
Инкремент и декремент
Операнд префиксной операции ++ увеличивается на 1. Операнд должен быть lvalue. Тип операнда должен быть арифметическим. Результатом является новое значение операнда, оно считается lvalue. Выражение ++x эквивалентно x+=1. Для уточнения преобразований можно обратиться к описанию сложения и операций присваивания .
Префиксная операция -- сводится к уменьшению на 1 и выполняется аналогично префиксной операции ++.
Мультипликативные операции
Мультипликативные операции *, /, и % выполняются слева направо.
Мультипликативное-выражение: унарное-выражение мультипликативное-выражение * унарное-выражение мультипликативное-выражение / унарное-выражение мультипликативное-выражение % унарное-выражение
Операнды операций * и / должны иметь арифметический тип, операнды для % должны быть целочисленного типа. Обычные арифметические преобразования производятся над операндами и определяют тип результата.
Бинарная операция * обозначает умножение.
Бинарная операция / вычисляет частное, а бинарная операция % вычисляет остаток от деления первого выражения на второе. Если второй операнд у / или % есть 0, результат неопределен, иначе (a/b)*b + a%b должно равняться a.
Аддитивные операции + и - выполняются слева направо, при этом происходят обычные арифметические преобразования операндов арифметического типа.
аддитивное-выражение: мультипликативное-выражение аддитивное выражение + мультипликативное-выражение аддитивное-выражение - мультипликативное-выражение
Операнды должны быть арифметического типа. Результатом операции + является сумма операндов. Результатом операции - будет разность операндов.
Операции сдвига
Операции сдвигов << и >> выполняются слева направо.
сдвиговое-выражение: аддитивное-выражение сдвиговое-выражение << аддитивное выражение сдвиговое-выражение >> аддитивное выражение
Операнды должны быть целочисленного типа, и над ними производятся стандартные целочисленные преобразования. Тип результата совпадает с типом преобразованного левого операнда. Результат не определен, если правый операнд отрицателен или больше или равен числу разрядов в двоичном представлении преобразованного левого операнда. Значением выражения E1<<E2 будет E1 (рассматриваемое как набор разрядов), сдвинутое влево на E2 разрядов, причем освободившиеся разряды заполняются нулями. Значением выражения E1>>E2 будет E1, сдвинутое вправо на E2 разрядов. Если E1 беззнакового типа или имеет неотрицательное значение, сдвиг вправо — логический (заполнение нулями), иначе производится заполнение единицами.
Операции отношения
Операции отношения выполняются слева направо, но этот факт мало что дает, ибо выражение a<b<c означает (a<b)<c, а вовсе не (a<b)&&(b<c).
выражение-отношения: сдвиговое-выражение выражение-отношения < сдвиговое-выражение выражение-отношения > сдвиговое-выражение выражение-отношения <= сдвиговое-выражение выражение-отношения >= сдвиговое-выражение
Операнды должны быть арифметического типа. Операции < (меньше чем), > (больше чем), <= (меньше или равно) и >= (больше или равно) дают результат 0, если указанное отношение не выполняется, и 1, если оно выполняется. Тип результата int.
Над арифметическими операндами выполняются обычные арифметические преобразования.
Операции сравнения на равенство
выражение-равенства: выражение-отношения выражение-равенства == выражение-отношения выражение-равенства != выражение-отношения
Операции == (равно) и != (не равно) аналогичны операциям отношения, за исключением того, что их приоритет ниже. (Таким образом, операция a<b == c<d дает результат 1, если выражения a<b и c<d имеют одно и то же значение.)
Поразрядная операция И
выражение-И: выражение-равенства выражение-И & выражение-равенства
Выполняются обычные арифметические преобразования, результат — поразрядная функция «И» от операндов. Операция применима только к целочисленным операндам.
Поразрядная операция исключающее ИЛИ
выражение-исключающего-ИЛИ: выражение-И выражение-исключающего-ИЛИ ^ выражение-И
Выполняются обычные арифметические преобразования, результат — поразрядная исключающая функция «ИЛИ» от операндов. Операция применима только к целочисленным операндам.
Поразрядная (включающая) операция ИЛИ
выражение-ИЛИ: выражение-исключающего-ИЛИ выражение-ИЛИ | выражение-исключающего-ИЛИ
Выполняются обычные арифметические преобразования, результат — поразрядная функция «ИЛИ» от операндов. Операция применима только к целочисленным типам.
Логическая операция И
логическое-выражение-И: выражение-ИЛИ логическое-выражение-И && выражение-ИЛИ
Операции && выполняются слева направо. Такая операция дает результат 1, если оба операнда ее отличны от нуля, иначе результат — 0. В отличие от & при операции && гарантируется вычисление слева направо, более того, второй операнд не вычисляется, если первый операнд равен 0.
Операнды не обязательно имеют одинаковый тип, но каждый должен быть арифметического типа. Тип результата int. Все побочные эффекты вычисления первого выражения могут возникать до вычисления второго выражения.
Логическая операция ИЛИ
логическое-выражение-ИЛИ: логическое-выражение-И логическое-выражение-ИЛИ || логическое-выражение-И
Операции || выполняются слева направо. Результат операции 1, если один из ее операндов отличен от нуля, иначе результат - 0. В отличие от | при операции || гарантируется вычисление слева направо, более того, второй операнд не вычисляется, если значение первого операнда отлично от нуля.
Операнды не обязательно имеют одинаковый тип, но каждый должен быть арифметического типа. Тип результата int. Все побочные эффекты вычисления первого выражения могут возникать до вычисления второго выражения.
Операция условия
выражение-условия: логическое-выражение-ИЛИ логическое-выражение-ИЛИ ? выражение : выражение-условия
Условные выражения выполняются слева направо. Первое выражение должно быть арифметического типа. Оно вычисляется, и, если результат его отличен от нуля, то результатом условного выражения будет значение второго выражения, иначе результат — значение третьего выражения. Все побочные эффекты вычисления первого выражения могут возникать до вычисления второго или третьего выражения.
Вычисляется только второе или третье выражение (но не оба).
Существует несколько операций присваивания, все они выполняются справа налево. Для всех них требуется, чтобы левым операндом был lvalue. Тип выражения присваивания совпадает с типом левого операнда. Результат операции присваивание — значение, хранящееся в левом операнде после того как произошло присваивание. Результат является lvalue.
выражение-присваивания: выражение-условия унарное-выражение операция-присваивания выражение-присваивания операция-присваивания: один из = *= /= %= += -= >>= <<= &= ^= |=
При простом присваивании ( = ) значение выражения заменяет собой значение объекта, с которым сопоставляется левый операнд. Если оба операнда арифметического типа, правый операнд, прежде чем произойдет присваивание, преобразуется к типу левого операнда. Правый операнд преобразуется к типу левого операнда, прежде выполнения присваивания.
Выполнение выражение вида E1 op= E2 эквивалентно выполнению E1 = E1 op (E2), однако E1 вычисляется лишь один раз.
Операция запятая
Операции запятая выполняются слева направо.
выражение: выражение-присваивания выражение , выражение-присваивания
Пара выражений, разделенных запятой, вычисляется слева направо и значение левого выражения уничтожается. Все побочные эффекты вычисления левого выражения могут возникать до вычисления правого выражения. Тип и значение результата совпадают с типом и значением правого выражения. Результат является lvalue, если таковым является правое выражение.
В контекстах, где запятая имеет специальное значение, скажем в списке фактических параметров функции или в списке инициализаторов, описанная здесь операция запятая может появляться только в скобках, например, вызов функции
f(a,(t=3,t+2),c);
содержит три параметра, причем второй имеет значение 5.