А8.9. Объявление typedef
Объявления, в которых спецификатор класса памяти есть typedef, не объявляют объектов - они определяют идентификаторы, представляющие собой имена типов. Эти идентификаторы называются typedef-именами.
typedef-имя:
идентификатор
Объявление typedef приписывает тип каждому имени своего объявителя обычным способом (см. A8.6.). С этого момента typedef-имя синтаксически эквивалентно ключевому слову спецификатора типа, обозначающему связанный с ним тип. Например, после
typedef long Blockno, *Blockptr;
typedef struct { double r, theta; } Complex;
допустимы следующие объявления:
Blockno b;
extern Blockptr bp;
Complex z, *zp;
b принадлежит типу long, bp - типу "указатель на long"; z - это структура заданного вида, a zp - принадлежит типу "указатель на такую структуру".
Объявление typedef не вводит новых типов, оно только дает имена типам, которые могли бы быть специфицированы и другим способом. Например, b имеет тот же тип, что и любой другой объект типа long.
typedef-имена могут быть перекрыты другими определениями во внутренней области видимости, но при условии, что в них присутствует указание типа. Например
extern Blockno;
не переобъявляет Blockno, а вот
extern int Blockno;
переобъявляет.
A8.10. Эквивалентность типов
Два списка спецификаторов типа эквивалентны, если они содержат одинаковый набор спецификаторов типа с учетом синонимичности названий (например, long и int long считаются одинаковыми типами). Структуры, объединения и перечисления с разными тегами считаются разными, а каждое безтеговое объединение, структура или перечисление представляет собой уникальный тип.
Два типа считаются совпадающими, если их абстрактные объявители (A8.8) после замены всех typedef-имен их типами и выбрасывания имен параметров функций составят эквивалентные списки спецификаторов типов. При сравнении учитываются размеры массивов и типы параметров функция.
A9. Инструкции
За исключением оговоренных случаев инструкции выполняются том порядке, как они написаны. Инструкции не имеют значений и выполняются, чтобы произвести определенные действия. Все виды инструкций можно разбить на несколько групп:
инструкция:
помеченная-инструкция
инструкция-выражение
составная-инструкция
инструкция-выбора
циклическая-инструкция
инструкция-перехода
A9.1. Помеченные инструкции
Инструкции может предшествовать метка.
помеченная-инструкция:
идентификатор : инструкция
case константное-выражение : инструкция
default : инструкция
Метка, состоящая из идентификатора, одновременно служит и объявлением этого идентификатора. Единственное назначение идентификатора-метки - указать место перехода для goto. Областью видимости идентификатора-метки является текущая функция. Так как метки имеют свое собственное пространство имен, они не "конфликтуют" с другими идентификаторами и не могут быть перекрыты (см. A11.1.).
case-метки и default-метки используются в инструкции switch (A9.4). Константное выражение в case должно быть целочисленным.
Сами по себе метки не изменяют порядка вычислений.
A9.2. Инструкция-выражение
Наиболее употребительный вид инструкции - это инструкция-выражение.
инструкция-выражение:
выражениенеоб ;
Чаще всего инструкция-выражение - это присваивание или вызов функции. Все действия, реализующие побочный эффект выражения, завершаются, прежде чем начинает выполняться следующая инструкция. Если выражение в инструкции опущено, то она называется пустой; пустая инструкция часто используется для обозначения пустого тела циклической инструкции или в качестве места для метки.
A9.3. Составная инструкция
Так как в местах, где по синтаксису полагается одна инструкция, иногда возникает необходимость выполнить несколько, предусматривается возможность задания составной инструкции (которую также называют блоком). Тело определения функции есть составная инструкция;
составная-инструкция:
{ список-объявлений список-инструкцийнеоб }
список-объявлений:
объявление
список-объявлений объявление
список-инструкций:
инструкция
список-инструкций инструкция
Если идентификатор из списка объявлений находился в области видимости объемлющего блока, то действие внешнего объявления при входе внутрь данного блока приостанавливается (A11.1), а после выхода из него возобновляется. Внутри блока идентификатор может быть объявлен только один раз. Для каждого отдельного пространства имен эти правила действуют независимо (A11); идентификаторы из разных пространств имен всегда различны.
Инициализация автоматических объектов осуществляется при каждом входе в блок и продолжается по мере продвижения по объявителям. При передаче управления внутрь блока никакие инициализации не выполняются. Инициализации статических объектов осуществляются только один раз перед запуском программы.
A9.4. Инструкции выбора
Инструкции выбора осуществляют отбор одной из нескольких альтернатив, определяющих порядок выполнения инструкций.
инструкция-выбора:
if ( выражение ) инструкция
if ( выражение ) инструкция else инструкция
switch ( выражение ) инструкция
Оба вида if-инструкций содержат выражение, которое должно иметь арифметический тип или тип указателя. Сначала вычисляется выражение со всеми его побочными эффектами, результат сравнивается с 0. В случае несовпадения с 0 выполняется первая подинструкция. В случае совпадения с 0 для второго типа if выполняется вторая подинструкция. Связанная со словом else неоднозначность разрешается тем, что слово else соотносят с последней еще не имеющей else if-инструкцией, расположенной в одном с этим else блоке и на одном уровне вложенности блоков.