Изменить стиль страницы

8.8 Typedef – определение типа

Описания, содержащие спецификатор_описания typedef, определяют идентификаторы, которы позднее могут использоваться так, как если бы они были ключевыми словами, именующими оновные или производные типы.

typedef-имя: идентификатор

Внутри области видимости описания, содержащего typedef, каждый идентификатор, возникающий как часть какого-либо опсателя, становится в этом месте синтаксически эквивалентным ключевому слову типа, которое именует тип, ассоциированный с идентификатором таким обрахом, как описывается в #8.4. Спецфикатор_описания typedef не может использоваться для члена класса. Имя класса или перечисления также является typedef-именем. Например, после

typedef int MILES, *KLICKSP; struct complex (* double re, im; *);

каждая из конструкций

MILES distance; extern KLICKSP metricp; complex z, *zp;

является допустимым описанием; distance имеет тип int, metricp имеет тип «указатель на int».

typedef вводит не новые типы, но только синонимы для тпов, которые могли бы быть определены другим путем. Так в приведенном выше примере distance рассматривается как имеющая в точности тот же тип, что и любой другой int объект.

Но описание класса вводит новый тип. Например:

struct X (* int a; *); struct Y (* int a; *); X a1; Y a2; int a3;

описывает три переменных трех различных типов.

Описание вида

описание_имени: сост идентификатор ; enum идентификатор ;

специфицирует, что идентификатор является именем некотрого (возможно, еще не определенного) класса или перечислния. Такие описания позволяют описывать классы, ссылающихся друг на друга. Например:

class vector;

class matrix (* // ... friend vector operator*(matrix amp;, vector amp;); *);

class vector (* // ... friend matrix operator*(matrix amp;, vector amp;); *);

8.9 Перегруженные имена функций

В тех случаях, когда для одного имени определено неколько (различных) описаний функций, это имя называется прегруженным. При использовании этого имени правильная функция выбирается с помощью сравнения типов фактических параметров с типами формальных параметров в описаниях функций.

Поиск того, какую функцию вызвать, осуществляется в три отдельных шага:

Искать точно соответствующую и использовать, если найдна.

Искать соответствующую с использованием стандартных пробразований (#6.6-8) и использовать любую найденную.

Искать соответствующую с использованием определенных пользователем преобразований (#6.5.6). Если найдено единтвенное множество преобразований, использовать ее.

Ноль, char или short считаются точно соответствующими формальному параметру типа int. Float считаются точно сооветствующими формальному параметру типа double.

Над параметром перегруженной функции выполняются только следующе преобразования: int в long, int в double и преобрзования указателей и ссылок (#6.7-8).

Для того, чтобы перегрузить имя функции не члена и не функции operator, любому описанию функции должно предшестввать описание overload, см. #8.1. Например:

overload abs; double abs(double); int abs(int);

abs(1); // вызывается abs(int); abs(1.0); // вызывается abs(double);

Например:

class X (* ... X (int); *); class Y (* ... Y (int); *);

class Z (* ... Z (char*); *);

overload int f (X), f (Y); overload int g (X), g (Z);

f (1); // недопустимо: f(X(1)) или f(Y(1)) g (1); // g(X(1)) g («asdf»); // g(Z(«asdf»))

Операция взятия адреса amp; может применяться к перегруженому имени только в присваивании или инициализации, когда ожидаемый тип определяет, адрес какой функции брать. Напрмер:

int operator=(matrix amp;, matrix amp;); int operator=(vector amp;, vector amp;); int (*pfm)(matrix amp;, matrix amp;) = amp;operator=; int (*pfv)(vector amp;, vector amp;) = amp;operator=; int (*pfx)(...) = amp;operator=;

8.10 Описания перечислений

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

enum_спецификатор: enum идентификатор opt (* enum_список *)

enum_список: перечислитель enum_список , перечислитель

перечислитель: идентификатор идентификатор = константное_выражение

Идентификаторы в enum-списке описаны как константы и мгут появляться во всех местах, где требуются константы. Если не появляется ни одного перечислителя с =, то значения сооветствующих констант начинаются с 0 и возрастают на 1 по мере чтения описания слева нарпаво. Перечислитель с = дает ассоцированному с ним идентификатору указанное значение; последущие идентификаторы продолжают прогрессию от присвоенного знчения.

Имена перечислителей должны быть отличными от имен обычных переменных. Имена перечислителей с разными константми тоже должны быть различны. Значения перечислителей не обзательно должны быть различными.

Роль идентификатора в спецификаторе перечисления enum_спецификатор полностью аналогична роли имени класса; он именует определенный нутератор. Например:

enum color (* red, yellow, green=20, blue *); color col = red;

color *cp = amp;col; if (*cp == blue) // ...

делает color именем типа, описывающего различные цвета, и затем описывает col как объект этого типа, а cp как указтель на объект этого типа. Возможные значения лежат во мнжестве (* 0, 1, 20, 21 *).

8.11 Описание Asm

Описание Asm имеет вид

asm ( строка );

Смысл описания asm неопределен. Обычно оно используется для передачи информации ассемблеру через компилятор.

9. Операторы

Операторы выполняются последовательно во всех случаях кроме особо оговоренных.

9.1 Оператор выражение

Большинство операторов является операторами выражение, которые имеют вид

выражение ;

Обычно операторы выражение являются присваиваниями и взовами функций.

9.2 Составной оператор, или блок

Составной оператор (называемый также «блок», что эквивлентно) дает возможность использовать несколько операторов в том месте, где предполагается использование одного:

составной_оператор: (* список_операторов opt *)

список_операторов: оператор оператор список_операторов

Обратите внимание, что описание – это вариант оператора (#9.14).

9.3 Условный оператор

Есть два вида условных операторов

if ( выражение ) оператор if ( выражение ) оператор else оператор

Выражение должно быть арифметического или указательного типа или классового типа, для которого определено преобразвание в арифметический или указательный тип (см. #8.5.6). Вчисляется выражение, и если оно не ноль, то выполняется певый подоператор. Если используется «else», то второй подоператор выполняется, если выражение есть 0. Как обычно, неоднозначность «else» разрешается посредством того, что else связывается с последним встречнным if, не имеющим else.