А 7.4. Унарные операторы
Выражения с унарными операторами выполняются справа налево.
А 7. Выражения 259
++
—
sizeof sizeof ( имя-типа )
унарный-оператор: один из
& * + !
А
Префиксные операторы инкремента и декремента
Унарное выражение, перед которым стоит ++ или есть унарное вы- ражение. Операнд увеличивается (++) или уменьшается на
Значением выражения является значение его операнда после увеличе- ния (уменьшения). Операнд всегда должен быть lvalue; информация об огра- ничениях на операнд и о деталях операции содержится в А7.7, где обсуж- даются аддитивные операторы, и в где рассматривается присваи- вание. Результат инкрементирования и декрементирования не есть lvalue.
А 7.4.2. Оператор получения адреса
Унарный оператор & обозначает операцию получения адреса своего опе- ранда. Операнд должен быть либо lvalue, не ссылающимся ни на битовое поле, ни на объект, объявленный как register, либо иметь тип "функция".
Результат - указатель на объект (или функцию), адресуемый этим lvalue.
Если тип операнда есть Т, то типом результата является "указатель на Т".
А 7.4.3. Оператор косвенного доступа
Унарный оператор * обозначает операцию косвенного доступа (раскры- тия указателя), возвращающую объект (или функцию), на который ука- зывает ее операнд. Результат есть lvalue, если операнд - указатель на объ- ект арифметического типа или на объект типа "структура", "объединение"
или "указатель". Если тип выражения - "указатель на то тип результа- та -
Т.
А 7.4.4. Оператор унарный плюс
Операнд унарного + должен иметь арифметический тип, результат - значение операнда. Целочисленный операнд подвергается целочисленно- му повышению. Типом результата является повышенный тип операнда.
Унарный + был добавлен для симметрии с унарным -.
А 7.4.5. Оператор унарный минус
Операнд для унарного - должен иметь арифметический тип, резуль- тат - значение операнда с противоположным знаком. Целочисленный
А. Справочное руководство операнд подвергается целочисленному повышению. Отрицательное значе- ние от беззнаковой величины вычисляется вычитанием из при- веденного к повышенному типу операнда, где птах - максимальное чис- ло повышенного типа; однако минус нуль есть нуль. Типом результата будет повышенный тип операнда.
А 7.4.6. Оператор побитового отрицания
Операнд оператора должен иметь целочисленный результат - дополнение операнда до единиц по всем разрядам. Выполняется целочис- ленное повышение типа операнда. Если операнд беззнаковый, то результат получается вычитанием его значения из самого большого числа повышен- ного типа. Если операнд знаковый, то результат вычисляется посредством приведения "повышенного операнда" к беззнаковому типу, выполнения операции и обратного приведения его к знаковому типу. Тип результа- та - повышенный тип операнда.
А 7.4.7. Оператор логического отрицания
Операнд оператора ! должен иметь арифметический тип или быть ука- зателем. Результат равен если сравнение операнда с 0 дает истину, и ра- вен 0 в противном случае. Тип результата -
А 7.4.8. Оператор определения размера sizeof
Оператор sizeof дает число байтов, требуемое для хранения объекта того типа, который имеет его операнд. Операнд - либо выражение (кото- рое не вычисляется), либо имя типа, записанное в скобках. Примененный к char оператор sizeof дает 1. Для массива результат равняется общему количеству байтов в массиве, для структуры или объединения -
числу байтов в включая и байты-заполнители, которые понадобились бы, если бы из элементов составлялся массив. Размер массива из п эле- ментов всегда равняется п, помноженному на размер отдельного его эле- мента. Данный оператор нельзя применять к операнду типа "функция",
к незавершенному типу и к битовому полю. Результат - беззнаковая це- лочисленная константа; конкретный ее тип зависит от реализации. В стан- дартном заголовочном файле h> (см. приложение В)
тип опре- деляется под именем size_t.
Оператор приведения типаИмя типа, записанное перед унарным выражением в скобках, вызыва- ет приведение значения этого выражения к указанному типу.
(
7. Выражения 261
Данная конструкция называется приведением. Имена типов даны в
Результат преобразований описан в А6. Выражение с приведением типа не является lvalue.
А 7.6. Мультипликативные операторы
Мультипликативные операторы *, / и % выполняются слева направо.
мулыпипликативное-выражение * выражение-приведенное-к-типу
мулыпипликативное-выражение / выражение-приведенное-к-типу
% выражение-приведенное-к-типу
Операнды операторов * и быть арифметического типа, опе- ратора % - целочисленного типа. Над операндами осуществляются обыч- ные арифметические преобразования, которые приводят их значения к типу результата.
Бинарный оператор * обозначает умножение.
Бинарный оператор / получает частное, а % - остаток от деления перво- го операнда на второй; если второй операнд есть 0, то результат не опреде- лен. В противном случае всегда выполняется соотношение:
+ a%b равняется а. Если оба операнда не отрицательные, то остаток не отрица- тельный и меньше делителя; в противном случае стандарт гарантирует только одно: что абсолютное значение остатка меньше абсолютного зна- чения делителя.
А 7.7. Аддитивные операторы
Аддитивные операторы + и - выполняются слева направо. Если опе- ранды имеют арифметический тип, то осуществляются обычные арифме- тические преобразования. Для каждого оператора существует еще не- сколько дополнительных сочетаний типов.
-выражение
аддитивное-выражение +
- мулыпипликативное-выражение
Результат выполнения оператора + есть сумма его операндов. Указа- тель на объект в массиве можно складывать с целочисленным значением.
При этом последнее преобразуется в адресное смещение посредством ум- ножения его на размер объекта, на который ссылается указатель. Сумма является указателем на объект того же типа; только ссылается этот указа- тель на другой объект же массива, отстоящий от первоначального со- ответственно вычисленному смещению. Так, если Р - указатель на объект
262 Приложение А. Справочное руководство в массиве, то
- указатель на следующий объект того же массива. Если полученный в результате суммирования указатель указывает за границы массива, то, кроме случая, когда он указывает на место, находящееся не- посредственно за концом результат будет неопределенным.
Возможность для
указателя указывать на элемент, расположенный сразу за концом массива, является новой. Тем самым узаконена общепринятая практика организации циклического перебора элементов массива.
Результат выполнения оператора - (минус) есть разность операндов.
Из указателя можно вычитать значение любого целочисленного типа с теми же преобразованиями и при тех же условиях, что и в сложении.
Если к двум указателям на объекты одного и того же типа применить оператор вычитания, то в результате получится целочисленное значение со знаком, представляющее собой расстояние между объектами, на кото- рые указывают эти указатели; указатель на следующий объект на 1 боль- ше указателя на предыдущий объект. Тип результата зависит от реализа- ции; в стандартном заголовочном файле h> он определен под име- нем pt
_t. Значение не определено, если указатели указывают на объ- екты не одного и же массива; однако если Р указывает на последний элемент массива, то имеет значение, равное 1.
Операторы сдвигаОператоры сдвига и
выполняются слева направо. Для обоих операторов каждый операнд должен иметь целочисленный тип, и каждый из них подвергается целочисленному повышению. Тип результата совпа- дает с повышенным типом левого операнда. Результат не определен, если правый операнд отрицателен или его значение превышает число битов в типе левого выражения или равно ему.
сдвиговое -выражение: аддитивное-выражение аддитивное-выражениеЗначение равно значению Е1 (рассматриваемому как цепочка би- тов), сдвинутому влево на Е2 битов; при отсутствии переполнения такая операция эквивалентна умножению на
Значение равно значе- нию сдвинутому вправо на Е2 битовые позиции. Если Е1 - беззнаковое или имеет неотрицательное значение, то правый сдвиг эквивалентен де- лению на в противном случае результат зависит от реализации.
.:
- . - .
А 7.9. Операторы отношенияОператоры отношения выполняются слева однако это свой- ство едва ли может оказаться полезным; согласно грамматике языка вы-
А 7. Выражения 263 трактуется так же, как а результат вычисления может быть только 0 или
выражение-отношения:выражение-отношения < выражение-отношения > выражение-отношения <= сдвиговое-выражениевыражение-отношения >=
сдвиговое-выражениеОператоры: < (меньше), > (больше), <= (меньше или равно) и >= (больше или равно) — все выдают 0, если специфицируемое отношение ложно, и 1, если оно истинно. Тип результата - int. Над арифметическими операндами вы- полняются обычные арифметические преобразования. Можно сравнивать указатели на объекты одного и того же типа (без учета результат будет зависеть от относительного расположения в памяти. До- пускается, однако, сравнение указателей на разные части одного и того же объекта: если два указателя указывают на один и тот же простой то они равны;
они указывают на элементы одной структуры, то указатель на элемент с более
поздним объявлением в структуре больше; если указате- ли указывают на элементы одного и же объединения, то они равны;
если указатели указывают на элементы некоторого массива, то сравнение этих указателей эквивалентно сравнению их индексов. Если Р указывает на последний элемент массива, то больше, чем Р, хотя указывает за границы
В остальных случаях результат сравнения не определен.
Эти правила несколько ослабили ограничения, установленные в первой ре- дакции языка. Они позволяют сравнивать указатели на различные элемен- ты структуры и объединения и легализуют сравнение с указателем на мес- которое расположено непосредственно за концом массива.
А Операторы равенствавыражение-равенства:выражение-равенства ==
выражение-равенства ! =
выражение-отношенияОператоры == (равно) и ! = (не равно) аналогичны операторам отноше- ния с той лишь разницей, что имеют более низкий приоритет. (Таким образом, a
Операторы равенства подчиняются тем же правилам, что и операторы отношения. Кроме того, они дают возможность сравнивать указатель с целочисленным константным выражением, значение которого равно нулю, и с указателем на void (см.
264 Приложение А. Справочное руководство
А Оператор побитового Ивыражение-равенстваИ-выражение &
Выполняются
обычные арифметические преобразования; результат - побитовое
И операндов. Оператор применяется только к целочисленным операндам.
Оператор побитового исключающего
ИЛИИ-выражениеисключающее-ИЛИ-выражение И-выражениеВыполняются обычные арифметические преобразования; результат - побитовое исключающее
ИЛИ операндов. Оператор применяется только к целочисленным операндам.
Оператор побитового
ИЛИИЛИ-выражение:исключающее-ИЛИ-выражениеИЛИ-выражение !
исключающее-ИЛИ-выражениеВыполняются обычные арифметические преобразования; результат
ИЛИ операндов. Оператор применяется только к целочислен- ным операндам.
А
Оператор логического
ИИЛИ-выражение &&
ИЛИ-выражениеОператоры && выполняются слева направо. Оператор && выдает 1, если оба операнда не равны нулю, и 0 в противном случае. В отличие от гарантирует, что вычисления будут проводиться слева направо: вычис- ляется первый операнд со всеми побочными эффектами; если он равен О,
то значение выражения есть 0. В противном случае вычисляется правый операнд, и, если он равен 0, то значение выражения есть 0, в противном случае оно равно
Операнды могут принадлежать к разным типам, но при этом каждый из них должен иметь либо арифметический тип, либо быть указателем.
Тип результата int.
7. Выражения 265
Оператор логического
ИЛИлогическое-ИЛИ-выражение логическое-И-выражениеОператоры выполняются слева направо. Оператор выдает если по крайней мере один из операндов не равен нулю, и 0 в противном случае.
В отличие от оператор гарантирует, что вычисления будут прово- диться слева направо: вычисляется первый операнд, включая все побоч- ные эффекты; если он не равен 0, то значение выражения есть В против- ном случае вычисляется правый операнд, и если он не равен 0, то значение выражения есть в противном случае оно равно 0.
Операнды могут принадлежать разным типам, но операнд должен иметь либо арифметический тип, либо быть указателем. Тип результата -
Условный оператор
условное - выражение:логическое -ИЛИ- выражениелогическое-ИЛИ-выражение ?
выражениеВычисляется первое выражение, включая все побочные эффекты; если оно не равно 0, то
результат есть значение второго выражения, в против- ном случае - значение третьего выражения. Вычисляется только один из двух последних операндов: второй или третий. Если второй и третий операнды арифметические, то выполняются обычные арифметические преобразования, приводящие к некоторому общему типу, который и бу- дет типом результата. Если оба операнда имеют тип void, или являются структурами или объединениями одного и того же типа, или представля- ют собой указатели на объекты одного и того же типа, то результат будет иметь тот же тип, что и операнды. Если один из операндов имеет тип "ука- затель", а другой является константой 0, то 0 приводится к типу "указа- тель", этот же тип будет иметь и результат. Если один операнд является указателем на void, а второй - указателем другого типа, то последний пре- образуется в указатель на void, который и будет типом результата.
При сравнении типов указателей типов (А8.2) объек- тов, на которые указатели ссылаются, во внимание не принимаются, но тип результата наследует квалификаторы обеих ветвей условного выра- жения.
А Выражения присваиванияСуществует несколько операторов присваивания; они выполняются справа налево.
266 Приложение А. Справочное руководство
выражение-присваивания:условное оператор-присваивания выражение-присваиванияоператор-присваивания: один из
/= %=
-=
&=
:=
Операторы присваивания в качестве левого операнда требуют lvalue, при- чем модифицируемого; это значит, что оно не может быть массивом, или иметь незавершенный тип, или быть функцией. Тип левого операнда, кро- ме не может иметь const; и, если он является струк- турой или в них не должно быть элементов или подэле- ментов (для вложенных структур или объединений) с const.
Тип выражения присваивания соответствует типу левого операн- да, а значение равно значению его левого операнда после завершения при- сваивания.
В простом присваивании с оператором = значение выражения замеща- ет объект, к которому обращается lvalue. При этом должно выполняться одно из следующих условий: оба операнда имеют арифметический тип
(если типы операндов разные, правый операнд приводится к типу левого операнда); оба операнда есть структуры или объединения одного и того же типа;
один операнд есть указатель, а другой - указатель на void; левый операнд - указатель, а правый - константное выражение со значением 0;
оба операнда - указатели на функции или объекты, имеющие одинаковый тип (за исключением возможного отсутствия const или volatile у пра- вого операнда).
Е1
ор = эквивалентно
Е1 = Е1
исключением: Е1 вычисляется только один раз.
Оператор запятаявыражение:выражение-присваиванияДва выражения, разделенные запятой, вычисляются слева направо, и зна- чение левого выражения отбрасывается. Тип и значение результата со- впадают с типом и значением правого операнда. Вычисление всех побоч- ных эффектов левого операнда завершается перед началом вычисления правого операнда. В контексте, в котором запятая имеет специальное зна- чение, например в списках аргументов функций (А7.3.2) или в списках инициализаторов
(здесь в качестве синтаксических единиц фигу-
7. Выражения 267рируют выражения присваивания), оператор запятая может появиться только в группирующих скобках. Например, в f ( a , (t=3, t+2), с)
три аргумента, из которых второй имеет значение 5.
Константные выраженияСинтаксически, константное выражение - это выражение с ограничен- ным подмножеством операторов:
условное -выражениеПри указании case-меток в переключателе, задании границ массивов и длин полей битов, на месте значений перечислимых констант и иници- ализаторов, а также в некоторых выражениях для препроцессора требу- ются выражения, вычисление которых приводит к константе.
Константные выражения не могут содержать присваиваний, операто- ров инкрементирования и декрементирования, вызовов функций и опе- раторов-запятых; перечисленные ограничения не распространяются на операнд оператора
Если требуется получить целочисленное кон- стантное выражение, то его операнды должны состоять из целых, пере- числимых символьных констант и констант с плавающей точкой;
приведения должны специфицировать целочисленный тип,
а любая константа с плавающей точкой - приводиться к целому. Из этого следует, что в константном выражении не может быть массивов, опера- ций косвенного обращения (раскрытия указателя), получения адреса и доступа к полям структуры. (Однако для sizeof возможны операнды любого вида.)
Для константных выражений в инициализаторах допускается боль- шая свобода;
операндами могут быть константы любого типа, а к внеш- ним или статическим объектам и внешним и статическим массивам, ин- дексируемым константными выражениями, возможно применять унар- ный оператор &. Унарный оператор & может также неявно присутство- вать при использовании массива без индекса или функции без списка аргументов. Вычисление инициализатора должно давать константу или адрес ранее объявленного внешнего или статического объекта плюс-ми- нус константа.
Меньшая свобода допускается для целочисленных константных выра- жений, используемых после не разрешаются кон- станты типа enum и операции приведения типа. (См.