-
Notifications
You must be signed in to change notification settings - Fork 22
Home
-
В используемых в этой статье обозначениях синтаксические нетерминалы обозначаются курсивом, а терминалы - жирным шрифтом. Двоеточие (:), следующее за нетерминалом, означает начало его определения. Альтернативные определения перечислены на отдельных строках, за исключением случаев, когда им предшествуют слова "one of". Опциональная синтаксическая конструкция обозначается подстрочным "opt", так что
{
expression ₒₚₜ}
означает опциональное выражение в фигурных скобках.
- Смысл значения, хранимого в объекте или возвращаемого функцией, определен типом выражения. Типы подразделяются на объектные типы (типы, полностью описывающие объекты) и неполные типы (типы, описывающие объекты, но которым не хватает информации для определения их размера).
- Объект логического типа, определяемого ключевым словом
bool
, может хранить значенияtrue
иfalse
. - Объект символьного типа, определяемого ключевым словом
char
, может хранить любой символ базового набора символов. - Объект целочисленного типа, определяемого ключевыми словами
int
илиlong
, может хранить целое число от -2147483648 до +2147483647. - Символьный и целочисленный типы вместе называются целочисленными типами.
- Объект вещественного типа, определяемого ключевыми словами
float
илиdouble
, может хранить число с плавающей точкой от ??? до ???. - Целочисленные и вещественные типы вместе называются арифметическими типами.
-
Пустой тип, обозначаемый ключевым словом
void
обозначает пустое множество значений. Это неполный тип, который не может быть дополнен. - Из перечисленных выше типов можно составить любое число производных типов:
- Тип массива описывает непрерывно размещенный непустой набор объектов конкретного объектного типа, называемым типом элемента. Тип массива характеризуется типом элемента, но не его длиной.
- Тип структуры описывает последовательно размещенный непустой набор полей-объектов (и в некоторых случаях неполных массивов). Каждое поле именовано и имеет собственный тип.
- Тип функции описывает функцию. Функциональный тип характеризуется типом возвращаемого значения, количеством и типами параметров.
- Тип указателя может быть образован от любого типа, который будет называться указываемым типом. Указательный тип описывает объект, чье значение указывает на сущность указываемого типа.
- Целочисленные и указательные типы вместе называются скалярными типами.
- Типы массивов и структур вместе называются агрегатными типами.
- Тип массива неизвестного размера является неполным типом. Для идентификатора этого типа такой тип может быть дополнен обозначением размера в объявлении этого идентификатора.
- TODO
- TODO
- Выражение - последовательность операторов и операндов, задающая вычисление значения, указывающая на объект или функцию, генерирующая побочный эффект или любые комбинации из вышеперечисленного.
- Группировка операндов и операторов (то есть приоритет операторов) задаются синтаксисом. Порядок вычисления операндов определен только для операторов вызова
()
, логической конъюнкции&&
, логической дизъюнкции||
, условного оператора?:
и оператора последовательного исполнения,
. В прочих случаях порядок вычисления операндов не определен. - Если во время вычисления выражения возникает исключительное состояние (например, результат математически не определен или не может быть представлен значением своего типа), поведение не определено.
-
Синтаксис
primary-expression:
identifier
literal
(
expression)
-
Семантика
- Идентификатор является первичным выражением, если он был объявлен как объект (в этом случае это lvalue) или как функция. Использование необъявленного идентификатора - нарушение синтаксиса.
- Литерал является первичным выражением. Его тип зависит от вида и значения литерала, как было описано в разделе Литералы.
- Выражение в круглых скобках является первичным выражением. Его тип и значение идентичны типу и значению выражению внутри скобок. Это lvalue, если выражение без скобок lvalue.
-
Синтаксис
postfix-expression:
primary-expression
postfix-expression[
expression]
postfix-expression(
argument-expression-list ₒₚₜ)
postfix-expression.
identifier
postfix-expression->
identifier
postfix-expression++
postfix-expression—
argument-expression-list:
initializer
argument-expression-list,
initializer
-
Ограничения
- Первое выражение должно иметь тип массив Т, второе выражение должно иметь целочисленный тип. Результат имеет тип Т.
-
Семантика
- Постфиксное выражение, за которым следует выражение в квадратных скобках
[]
- вырезка элемента массива. Если объектE1
был объявлен как массив, то записьЕ1[Е2]
означает элемент с индексомЕ2
(отсчитывая с нуля) массиваЕ1
. - Последовательные операторы вырезки обозначают элемент многомерного массива.
- Постфиксное выражение, за которым следует выражение в квадратных скобках
-
Ограничения
- Первое выражение должно иметь тип функция, возвращающая Т. Результат вызова имеет тип Т.
-
Семантика
- Постфиксное выражение, за которым следует разделенный запятыми список выражений (возможно пустой) в круглых скобках
()
означают вызов функции. Левое выражение обозначает вызываемую функцию. Список выражений определяет аргументы функции. - Аргумент должен удовлетворять условиям инициализации типа соответствующему параметру, как это описано в разделе Инициализация. При подготовке к вызову функции каждому параметру присваивается значение соответствующего аргумента.
- Постфиксное выражение, за которым следует разделенный запятыми список выражений (возможно пустой) в круглых скобках
-
Ограничения
- Первый операнд оператора
.
должен иметь тип структура. Второй операнд должен называть поле этой структуры. - Первый операнд оператора
->
должен иметь тип указатель на структуру. Второй операнд должен называть поле этой структуры, на которую указывает левый операнд.
- Первый операнд оператора
-
Семантика
- Постфиксное выражение, за которым следует оператор
.
, а идентификатор называет поле структуры, обозначает поле структуры. Это lvalue, если левый операнд lvalue. Результат имеет тот же тип, который имеет поле структуры. - Постфиксное выражение, за которым следует оператор
->
, а идентификатор называет поле структуры, на которую указывает левый операнд, обозначает поле структуры. Это lvalue. Результат имеет тот же тип, который имеет поле структуры. - Если
E
- структура, то выражение(&E)->MOS
эквивалентноE.MOS
.
- Постфиксное выражение, за которым следует оператор
-
Ограничения
- Операнд постфиксных операторов инкремента или декремента должен иметь арифметический тип и быть модифицируемым lvalue.
-
Семантика
- Результатом постфиксного оператора
++
является значение операнда. После получения результата значение операнда увеличивается на1
. - Результатом постфиксного оператора
--
является значение операнда. После получения результата значение операнда уменьшается на1
.
- Результатом постфиксного оператора
-
Синтаксис
unary-expression:
postfix-expression
++
unary-expression
--
unary-expression
unary-operator unary-expression
unary-operator: one of
&
*
-
̃
!
-
Ограничения
- Операнд префиксных операторов инкремента или декремента должен иметь арифметический тип и быть модифицируемым lvalue.
-
Семантика
- Значение операнда префиксного оператора
++
увеличивается на1
. Результатом является новое значение операнда. - Значение операнда префиксного оператора
--
уменьшается на1
. Результатом является новое значение операнда.
- Значение операнда префиксного оператора
-
Ограничения
- Операнд унарного оператора
&
должен быть lvalue. - Операнд унарного оператора
*
должен иметь тип указатель.
- Операнд унарного оператора
-
Семантика
- Унарный оператор
&
возвращает адрес своего операнда. Если операнд является результатом унарного оператора*
, ни этот оператор, ни оператор&
не вычисляются, и результат такой, как если бы оба были опущены, за исключением того, что ограничения на операторы все еще применяются, и результат не является lvalue. В противном случае результатом является указатель на объект, обозначенный операндом. - Унарный оператор
*
обозначает косвенное обращение (разыменование). Если операнд указывает на объект, результатом будет lvalue, обозначающее объект. Если операнд имеет тип указатель на Т, результат будет иметь тип Т. Если указателю присвоено недопустимое значение, поведение унарного оператора*
не определено.
- Унарный оператор
-
Ограничения
- Операнд унарного оператора
+
должен иметь арифметический тип. - Операнд оператора
~
должен иметь целочисленный тип. - Операнд оператора
!
должен иметь скалярный тип.
- Операнд унарного оператора
-
Семантика
- Результатом унарного оператора
-
является значение его операнда с противоположным знаком. Тип результата совпадает с типом операнда. - Результатом оператора
~
является побитовое дополнение операнда (то есть каждый бит в результате устанавливается тогда и только тогда, когда соответствующий бит в операнде не установлен). Результат имеет целочисленный тип. - Результатом оператора логического отрицания
!
являетсяfalse
, если значение операнда равно начальному значению соответствующего типа;true
в обратном случае. Результат имеет логический тип.
- Результатом унарного оператора
-
Синтаксис
multiplicative-expression:
unary-expression
multiplicative-expression*
unary-expression
multiplicative-expression/
unary-expression
multiplicative-expression%
unary-expression -
Ограничения
- Операнды операторов
*
и/
должны иметь арифметический тип. - Операнды оператора
%
должны иметь целочисленный тип.
- Операнды операторов
-
Семантика
- Результатом оператора
*
является произведение операндов. - Результатом оператора
/
является частное от деления первого операнда на второй; результат оператора%
- остаток. В обеих операциях, если значение второго операнда равно нулю, поведение не определено. - При делении целых чисел результатом оператора
/
является алгебраическое частное с отброшенной дробной частью.
- Результатом оператора
-
Синтаксис
additive-expression:
multiplicative-expression
additive-expression+
multiplicative-expression
additive-expression-
multiplicative-expression -
Ограничения
- Операнды операторов
+
и-
должны иметь арифметический тип.
- Операнды операторов
-
Семантика
- Результатом оператора
+
является сумма операндов. - Результатом оператора
-
является разность левого и правого операндов.
- Результатом оператора
-
Синтаксис
shift-expression:
additive-expression
shift-expression<<
additive-expression
shift-expression>>
additive-expression -
Ограничения
- Операнды операторов битового сдвига должны иметь целочисленный тип.
-
Семантика
- Результатом выражения
E1 << E2
являетсяE1
, сдвинутое влево наE2
бит; освобожденные биты заполняются нулями. - Результатом выражения
E1 >> E2
являетсяE1
, сдвинутое вправо наE2
бит.
- Результатом выражения
-
Синтаксис
relational-expression:
shift-expression
relational-expression<
shift-expression
relational-expression>
shift-expression
relational-expression<=
shift-expression
relational-expression>=
shift-expression -
Ограничения
- Операнды операторов сравнения должны иметь арифметический тип.
-
Семантика
- Каждый из операторов
<
("меньше"),>
("больше"),<=
("меньше или равно") и>=
("больше или равно") выдаетtrue
, если обозначенное отношение истинно, иfalse
, если оно ложно. Результат имеет логический тип.
- Каждый из операторов
-
Синтаксис
equality-expression:
relational-expression
equality-expression==
relational-expression
equality-expression!=
relational-expression -
Ограничения
- Одно из следующих условий должно выполняться:
- Оба операнда имеют арифметический тип;
- Оба операнда имеют совместимые типы;
- Один из операндов имеет тип указатель, а другой является литералом
null
.
- Одно из следующих условий должно выполняться:
-
Семантика
- Каждый из операторов
==
("равно") и!=
("не равно") выдаетtrue
, если обозначенное отношение истинно, иfalse
, если оно ложно. Результат имеет логический тип.
- Каждый из операторов
-
Синтаксис
and-expression:
equality-expression
and-expression&
equality-expression -
Ограничения
- Оба операнда должны иметь целочисленный тип.
-
Семантика
- Результат бинарного оператора
&
- битовая конъюнкция операндов.
- Результат бинарного оператора
-
Синтаксис
xor-expression:
and-expression
xor-expression^
and-expression -
Ограничения
- Оба операнда должны иметь целочисленный тип.
-
Семантика
- Результат бинарного оператора
^
- битовая строгая дизъюнкция операндов.
- Результат бинарного оператора
-
Синтаксис
or-expression:
xor-expression
or-expression|
xor-expression -
Ограничения
- Оба операнда должны иметь целочисленный тип.
-
Семантика
- Результат бинарного оператора
|
- битовая дизъюнкция операндов.
- Результат бинарного оператора
-
Синтаксис
logical-and-expression:
or-expression
logical-and-expression&&
or-expression -
Ограничения
- Оба операнда должны иметь скалярный тип.
-
Семантика
- Оператор
&&
выдаетtrue
, если оба операнда не равны начальному значению соответствующего типа; иначе оператор выдаетfalse
. - Оператор
&&
гарантирует вычисление слева направо. Если первый операнд равен начальному значению соответствующего типа, второй операнд не вычисляется.
- Оператор
-
Синтаксис
logical-or-expression:
logical-and-expression
logical-or-expression||
logical-and-expression -
Ограничения
- Оба операнда должны иметь скалярный тип.
-
Семантика
- Оператор
||
выдаетtrue
, если хотя бы один из операндов не равен начальному значению соответствующего типа; иначе оператор выдаетfalse
. - Оператор
||
гарантирует вычисление слева направо. Если первый операнд не равен начальному значению соответствующего типа, второй операнд не вычисляется.
- Оператор
-
Синтаксис
conditional-expression:
logical-or-expression
logical-or-expression?
expression:
conditional-expression -
Ограничения
- Первый операнд должен иметь скалярный тип.
- Одно из следующих условий должно выполняться для второго и третьего операндов:
- Оба операнда имеют арифметический тип;
- Оба операнда имеют совместимые типы;
- Один операнд имеет тип указатель, а другой является литералом
null
.
-
Семантика
- Сначала вычисляется первый операнд. Второй операнд вычисляется только если первый операнд не равен начальному значению соответствующего типа; третий операнд вычисляется только если первый операнд равен начальному значению соответствующего типа. Результатом является значение вычисленного (второго или третьего) операнда.
-
Синтаксис
assignment-expression:
conditional-expression
unary-expression assignment-operator initializer
assignment-operator: one of
=
*=
/=
%=
+=
-=
<<=
>>=
&=
ˆ=
|=
-
Ограничения
- Первый операнд оператора присваивания должен быть модифицируемым lvalue.
-
Семантика
- Оператор присваивания сохраняет значение в объекте, обозначенном первым операндом. Результат имеет значение и тип первого операнда после присваивания, но не является lvalue.
-
Ограничения
- Одно из следующих условий должно выполняться:
- Левый операнд имеет вещественный тип, и правый операнд имеет целочисленный тип;
- Левый операнд имеет тип указатель, и правый операнд является литералом
null
; - Операнды имеют совместимые типы.
- Одно из следующих условий должно выполняться:
-
Семантика
- При простом присваивании значение правого операнда конвертируется к типу присваивания и заменяет значение, хранящееся в объекте, указанном левым операндом.
-
Ограничения
- Операнды оператора составного присваивания должны удовлетворять требованиям соответствующего бинарного оператора
-
Семантика
- Составное присваивание вида
E1 op= E2
отличается от простого присваиванияE1 = E1 op E2
только тем, чтоE1
вычисляется только один раз.
- Составное присваивание вида
-
Синтаксис
expression:
assignment-expression
expression,
assignment-expression -
Семантика
- Сначала вычисляется левый операнд; его результат отбрасывается. Затем вычисляется правый операнд; результат имеет его тип и значение.
-
Синтаксис
constant-expression:
conditional-expression -
Описание
- Константное выражение может быть вычислено на этапе компиляции и использовано в любом месте, где может быть литерал.
-
Ограничения
- Константные выражения не могут содержать присваиваний, инкрементов, декрементов и вызовов функций.
-
Синтаксис
declaration:
variable-declaration;
function-declaration;
type-definition;
-
Ограничения
- В любой области видимости должно быть не больше одного объявления идентификатора, за исключением функций, как описано в разделе 9.1. Определения функций.
-
Семантика
- Объявление определяет интерпретацию набора идентификаторов.
-
Определение идентификатора – это объявление, которое:
- для объекта приводит к выделению памяти для этого объекта;
- для функции включает тело функции;
- для определений типов и констант перечисления является единственным объявлением идентификатора.
-
Синтаксис
type-specifier:
void
bool
char
short
int
long
float
double
FILE
struct-specifier
enum-specifier
typedef-name -
Синтаксис
- Сопоставление типов ключевым словам описано в разделе 2.3. Типы.
- Спецификаторы структур описаны в разделе 7.1.1. Спецификаторы структур.
- Спецификаторы перечислений описаны в разделе 7.1.2. Спецификаторы перечислений.
- Имена определенных типов описаны в разделе 7.5. Определения типов.
-
Синтаксис
struct-specifier:
struct
identifier ₒₚₜ{
struct-declaration-list}
struct
identifier
struct-declaration-list:
struct-declaration
struct-declaration-list struct-declaration
struct-declaration:
type-specifier declarator;
function-declaration;
-
Ограничения
- Структура не может содержать поле неполного или функционального типа (поэтому структура не может содержать экземпляр самой себя, но может содержать указатель на экземпляр самой себя).
-
Семантика
- Как было описано в разделе 2.3. Типы, структура - это тип, состоящий из последовательности полей, расположенных в памяти последовательно в обозначенном порядке.
- Если заголовок объявления структуры содержит идентификатор, то он является именем типа этой структуры, и может использоваться как
typedef-name
. - Конструкция
struct-declaration-list
объявляет новый тип в соответствующей области видимости. Этот тип не является полным, пока не достигнута}
, оканчивающая список полей структуры.
-
Синтаксис
enum-specifier:
enum
identifier ₒₚₜ{
enumerator-list}
enum
identifier ₒₚₜ{
enumerator-list,
}
enum
identifier
enumerator-list:
enumerator
enumerator-list,
enumerator
enumerator:
identifier
identifier=
constant-expression -
Ограничения
- Выражение, обозначающее значение константы перечисления, должно иметь целочисленный тип.
-
Семантика
- Конструкция
enumerator-list
объявляет новый тип в соответствующей области видимости. Этот тип не является полным, пока не достигнута}
, оканчивающая список констант перечисления. - Если заголовок объявления перечисления содержит идентификатор, то он является именем типа этого перечисления, и может использоваться как
typedef-name
. - Идентификаторы из списка перечисления объявляются как константы целочисленного типа. Конструкция
enumerator
c=
определяет константу перечисления как значение константного выражения. Если первая конструкцияenumerator
в списке перечисления не имеет=
, то значение соответствующей константы равно 0. Каждая последующая конструкцияenumerator
без=
определяет константу со значением, получаемым прибавлением 1 к значению предыдущей константы. - Значения констант одного и того же перечисления могут повторяться.
- Конструкция
-
Синтаксис
variable-declaration:
type-specifier init-declarator-list ₒₚₜ
init-declarator-list:
init-declarator
init-declarator-list,
init-declarator
init-declarator:
declarator
declarator=
initializer
declarator:
*
ₒₚₜ direct-declarator
direct-declarator:
identifier
direct-declarator[
assignment-expression ₒₚₜ]
-
Ограничения
- Объявление должно содержать хотя бы одно описание типа структуры или перечисления или хотя бы один декларатор.
- К концу объявления тип объявляемого объекта должен быть полным.
-
Семантика
- Каждый декларатор объявляет один идентификатор, и для каждого его появления в выражении указывает область видимости и тип, заданный спецификаторами объявления.
- В объявлении вида
T D
, гдеT
обозначает спецификатор типа, аD
- декларатор, содержащий некоторый идентификатор, тип, указанный для этого идентификатора, описывается индуктивно с использованием этой нотации. - Если в объявлении
T D
, гдеT
обозначает спецификатор типа, аD
- декларатор,D
имеет формуidentifier
, то декларатор объявляет переменную с именем идентификатора и типом T.
-
Семантика
- Если в объявлении
T D1
, гдеT
обозначает спецификатор типа, аD1
- декларатор,D1
имеет форму*D
, и объявлениеT D
задает объявляемому идентификатору тип T, то идентификатору задается тип указатель на Т.
- Если в объявлении
-
Ограничения
- Если
[]
содержат выражение, то это выражение описывает размер массива и должно иметь целочисленный тип. Если выражение является константным, то его значение должно быть больше нуля. - Тип элемента в деклараторе массива не должен быть функциональным.
- Если
-
Семантика
- Если в объявлении
T D1
, гдеT
обозначает спецификатор типа, аD1
- декларатор,D1
имеет формуD[N]
, и объявлениеT D
задает объявляемому идентификатору тип T, то идентификатору задается тип массив из N элементов типа Т, где N вычисляется при достижении данного объявления. - Если в объявлении
T D1
, гдеT
обозначает спецификатор типа, аD1
- декларатор,D1
имеет формуD[]
, и объявлениеT D
задает объявляемому идентификатору тип T, то идентификатору задается тип массив элементов типа Т, а размер будет задан инициализатором. - Если выражение размера массива отсутствует, то тип описанного массива является неполным. Он может быть дополнен инициализатором.
- Когда значение выражения, обозначающего размер массива, будет вычислено, оно должно быть больше 0. Размер массива не меняется в течении всего его времени жизни.
- Если в объявлении
-
Синтаксис
function-declaration:
return-type-specifier function-declarator(
parameter-list ₒₚₜ)
return-type-specicifier:
type-specifier*
ₒₚₜ
return-type-specicifier[
constant-expression ₒₚₜ]
function-declarator:
identifier
(
*
identifier)
parameter-list:
parameter-declaration
parameter-list,
parameter-declaration
parameter-declaration:
type-name
type-specifier declarator
function-declaration -
Ограничения
- Объявляемая функция не может возвращать значение функционального типа.
- Выражение, обозначающее размер возвращаемого массива должно иметь целочисленный тип.
-
Семантика
- Если в объявлении
T D
, гдеT
обозначает возвращаемый тип, аD
- декларатор функции,T
имеет формуtype-specifier
, то возвращаемый тип задается соответсвенно спецификатору типа, как это было описано в разделе 2.3. Типы. - Если в объявлении
T1 D
, гдеT1
обозначает возвращаемый тип, аD
- декларатор функции,T1
имеет формуТ*
, и объявлениеT
задает возвращаемый тип T, то возвращаемый тип задается как указатель на Т. - Если в объявлении
T1 D
, гдеT1
обозначает возвращаемый тип, аD
- декларатор функции,T1
имеет формуT[N]
, иT
задает возвращаемый тип T, то возвращаемый тип задается как массив из N элементов типа Т, где N вычисляется при достижении данного объявления. - Если в объявлении
T1 D
, гдеT1
обозначает возвращаемый тип, аD
- декларатор функции,T1
имеет формуT[]
, иT
задает возвращаемый тип T, то возвращаемый тип задается как массив элементов типа Т. - Если в объявлении декларатор функции имеет форму
identifier
, то объявление объявляет функцию с параметрами, обозначенными списком параметров и возвращающую значение такого типа, как было описано выше. - Если в объявлении декларатор функции имеет форму
, то объявление объявляет указатель на функцию с параметрами, обозначенными списком параметров и возвращающую значение такого типа, как было описано выше.(*
identifier)
- Список параметров определяет типы и имена для параметров функции.
- Параметр, определенный типом функция преобразуется в параметр с типом указатель на функцию.
- Если в объявлении
- TODO
-
Синтаксис
type-name:
variable-type-name
function-type-name
variable-type-name:
type-specifier*
ₒₚₜ abstract-declarator ₒₚₜ
abstract-declarator:
abstract-declarator ₒₚₜ[
assignment-expression ₒₚₜ]
function-type-name:
return-type-specifier function-pointer ₒₚₜ(
parameter-list ₒₚₜ)
function-pointer:
(
*
)
-
Семантика
- В некоторых контекстах необходимо указать тип. Это достигается при помощи конструкции имя типа, которая позволяет объявить объект или функцию, опуская идентификатор.
-
Синтаксис
initializer:
assignment-expression
{
initializer-list}
{
initializer-list,
}
initializer-list:
initializer
initializer-list,
initializer -
Ограничения
- Инициализатор для скалярного объекта должен быть одиночным выражением.
- Инициализатор для агрегатного объекта должен быть списком инициализации, как описано ниже, либо одиночным выражением совместимого типа.
- Если инициализатор агрегатного объекта имеет форму списка инициализации, то список должен содержать соответствующее количество подвыражений, равное количеству элементов массива или количеству полей структуры.
- Одно из следующих условий должно выполняться для инициализируемого объекта и для инициализатора:
- Объект имеет вещественный тип, и правый операнд имеет целочисленный тип;
- Левый операнд имеет тип указатель, и правый операнд является литералом
null
; - Операнды имеют совместимые типы.
-
Семантика
- Инициализатор определяет начальное значение, хранимое в объекте.
- Если объект не инициализируется явно, то:
- если объект имеет тип указатель, он инициализируется константой нулевого указателя;
- если объект имеет арифметический тип, он инициализируется нулем;
- если объект имеет агрегатный тип, каждый его элемент инициализируется по этим правилам.
- Каждый элемент списка инициализации инициализирует соответствующий элемент агрегатного объекта: элементы массива в порядке возрастания индекса, поля структур в порядке их объявления. Инициализация происходит в этом же порядке.
- Если в объявлении со списком инициализации агрегатный объект содержит агрегатные объекты, то правила инициализации применяются рекурсивно для соответствующего вложенного списка.
- Если инициализируется массив неизвестной длины, то его размер определяется количеством элементов списка инициализации. К концу инициализации массив имеет полный тип.
-
Синтаксис
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement -
Семантика
- Оператор обозначает действие. Операторы исполняются последовательно.
- Блок позволяет сгруппировать набор объявлений и операторов в одну синтаксическую единицу. Значения выражений, обозначающих длины массивов, и значения инициализаторов объектов будут вычислены тогда, когда объявление будет достигнуто в порядке исполнения.
-
Синтаксис
labeled-statement:
case
constant-expression:
statement
default
:
statement -
Ограничения
- Метки
case
иdefault
должны появляться только в оператореswitch
. Прочие ограничения на эти метки описаны в разделе "Оператор switch".
- Метки
-
Синтаксис
compound-statement:
{
block-item-list ₒₚₜ}
block-item-list:
block-item
block-item-list block-item
block-item:
declaration
statement -
Семантика
- Составной оператор - это блок.
-
Синтаксис
expression-statement:
expression ₒₚₜ;
-
Семантика
- Выражение оператора-выражения вычисляется для его побочных эффектов (например, присваиваний и вызовов функций).
-
Пустой оператор (состоящий только из
;
) не производит операций. - ПРИМЕР 1. В программе:
пустой оператор используется для предоставления пустого тела цикла оператору итерации.
char *s; /* ... */ while (*s++ != '\0') ;
- ПРИМЕР 2. Пустой оператор может использоваться для установки метки прямо перед закрывающей скобкой
}
составного оператора:while (loop1) { /* ... */ while (loop2) { /* ... */ if (want_out) goto end_loop1; /* ... */ } /* ... */ end_loop1: ; }
-
Синтаксис
selection-statement:
if
(
expression)
statement
if
(
expression)
statementelse
statement
switch
(
expression)
statement -
Семантика
- Оператор ветвления выбирает среди набора операторов в зависимости от значения управляющего выражения.
- Оператор ветвления - это блок, область видимости которого является строгим подмножеством области видимости включающего его блока. Каждый вложенный оператор также является блоком, область видимости которого является строгим подмножеством области видимости оператора ветвления.
-
Ограничения
- Управляющее выражение оператора
if
должно иметь скалярный тип.
- Управляющее выражение оператора
-
Семантика
- В обеих формах первый вложенный оператор исполняется, если значение управляющего выражения не равно 0. В форме
else
второй вложенный оператор исполняется, если значение управляющего выражения равно 0. Если первый вложенный оператор достигнут с помощью перехода на метку, второй вложенный оператор не исполняется. -
else
ассоциировано с ближайшим в лексическом смысле предыдущимif
.
- В обеих формах первый вложенный оператор исполняется, если значение управляющего выражения не равно 0. В форме
-
Ограничения
- Управляющее выражение оператора
switch
должно иметь целочисленный тип. - Выражение каждой метки
case
должно быть целочисленным константным выражением и никакие два выражения метокcase
в одном оператореswitch
не должны иметь совпадающих значений после преобразований. - В операторе
switch
должно быть не больше одной меткиdefault
. - Вложенный оператор
switch
может иметь свою меткуdefault
, а значения выражений метокcase
могут дублировать значения выражений метокcase
внешнего оператораswitch
.
- Управляющее выражение оператора
-
Семантика
- Оператор
switch
заставляет поток управления переходить к телу оператора, в или за него, в зависимости от значения управляющего выражения, а также от наличия меткиdefault
и значений любых метокcase
внутри тела оператора. Меткаcase
илиdefault
доступна только внутри ближайшего включающего оператораswitch
. - Если значение выражения метки
case
совпадает со значением управляющего выражения, поток исполнения переходит к оператору, следующему за этой меткой. Если таких метокcase
нет, но есть меткаdefault
, поток исполнения переходит к помеченному оператору. Если значения никаких выражений метокcase
не совпадают со значением управляющего выражения, и нет меткиdefault
, никакая часть оператораswitch
не исполняется. - ПРИМЕР. В программе:
объект с идентификатором
switch (expr) { int i = 4; f(i); case 0: i = 17; /* falls through into default code */ default: printf("%d\n", i); }
i
не будет инициализирован. Если значение управляющего выражения не равно 0, функцияprintf
обратится к неопределенному значению. Аналогично, вызов функцииf
не будет исполнен.
- Оператор
-
Синтаксис
iteration-statement:
while
(
expression)
statement
do
statementwhile
(
expression)
;
for
(
expression ₒₚₜ;
expression ₒₚₜ;
expression ₒₚₜ)
statement
for
(
declaration expression ₒₚₜ;
expression ₒₚₜ)
statement -
Ограничения
- Управляющее выражение оператора итерации должно иметь скалярный тип.
-
Семантика
- Оператор итерации вызывает повторное выполнение оператора, называемого телом цикла, до тех пор, пока результат управляющего выражения не станет равным 0.
- Оператор итерации - это блок, область видимости которого является строгим подмножеством области видимости включающего его блока. Тело цикла также является блоком, область видимости которого является строгим подмножеством области видимости оператора итерации.
- Вычисление управляющего выражения происходит перед каждым исполнением тела цикла.
- Вычисление управляющего выражения происходит после каждого исполнения тела цикла.
- Оператор вида
for
(
clause-1;
expression-2;
expression-3)
statement
ведет себя следующим образом: выражение expression-2 является управляющим выражением, которое вычисляется перед каждым выполнением тела цикла. Выражение expression-3 вычисляется после каждого выполнения тела цикла. Если clause-1 является объявлением, область видимости любых объявляемых им переменных - это оставшаяся часть объявления и весь цикл, включая два других выражения; оно исполняется перед первым вычислением управляющего выражения. Если clause-1 является выражением, оно вычисляется перед первый вычислением управляющего выражения. Таким образом, clause-1 определяет инициализацию цикла, возможно, объявляя одну или несколько переменных для использования в цикле; управляющее выражение expression-2 определяет вычисление, выполняемое перед каждой итерацией, так что выполнение цикла продолжается до тех пор, пока результат выражения не станет равным 0; а expression-3 определяет операцию (например, инкремент), которая выполняется после каждой итерации. - И clause-1, и expression-3 могут быть опущены. Опущенное expression-2 заменяется ненулевой константой.
-
Синтаксис
jump-statement:
continue
;
break
;
return
expression ₒₚₜ;
-
Семантика
- Оператор перехода означает безусловный переход.
-
Ограничения
- Оператор
continue
должен появляться только в теле (или быть телом) или оператора итерации.
- Оператор
-
Семантика
- Оператор
continue
завершает исполнение текущей итерации цикла и переходит к следующей. - ПРИМЕР. В программе:
оператор
for (/* ... */) { /* ... */ continue; /* ... */ contin:; }
continue
эквивалентен операторуgoto contin;
.
- Оператор
-
Ограничения
- Оператор
break
должен появляться только в теле (или быть телом) оператораswitch
или оператора итерации.
- Оператор
-
Семантика
- Оператор
break
завершает исполнение наименьшего по включению оператораswitch
или цикла.
- Оператор
-
Ограничения
- Оператор
return
с выражением не должен появляться в функции, возвращающей значение типа void. Операторreturn
без выражения должен появляться только в функции, возвращающей значение типа void.
- Оператор
-
Семантика
- Оператор
return
завершает исполнение текущей функции и возвращает управление ее вызывающей стороне. Функция может иметь любое количество операторовreturn
. - Если исполняется оператор
return
с выражением, значение выражения возвращается вызывающей стороне как значение выражения вызова функции. Если выражение имеет тип, отличный от типа возвращаемого значения функции, в которой оно появляется, значение преобразуется, как если бы оно было присвоено объекту, имеющему тип возвращаемого значения функции.
- Оператор
-
Синтаксис
translation-unit:
external-declaration
translation-unit external-declaration
external-declaration:
declaration
function-definition -
Семантика
- Текст программы после подстановок препроцессора называется единицей трансляции и состоит из последовательности внешних объявлений. Они называются "внешними", так как находятся вне какой-либо функции.
-
Синтаксис
function-definition:
function-declaration compound-statement -
Ограничения
- Возвращаемый тип функции должен быть пустым или любым объектным типом.
- Если декларатор содержит список параметров, то объявление каждого параметра должно содержать имя.
-
Семантика
- Декларатор в определении функции обозначает имя описываемой функции и идентификаторы ее параметров.
- Составной оператор в определении функции обозначает тело функции.
- Каждый идентификатор параметра является lvalue, который фактически объявлен в начале тела функции (и потому не может быть переопределено в теле функции кроме как во включающем блоке).
- При входе в функцию подсчитываются выражения размеров массивов, а значения каждого аргумента конвертируются к типу соответствующего параметра как если бы они были инициализированы.
- После инициализации всех параметров исполняется тело функции.
- Если достигнута
}
, завершающая определение функции, и значение вызова этой функции использовано вызывающим, поведение не определено.
-
Семантика
- Если объявление идентификатора имеет глобальную область видимости, то оно является внешним объявлением идентификатора.
- Если внешнее объявление не содержит инициализатор, и описываемый идентификатор имеет тип, отличный от функционального, то идентификатор инициализируется начальным значением, как было описано в разделе Инициализаторы.
- Вычисление значений внешних объектов происходит в порядке их появления в единице трансляции при запуске программы.
- TODO