Типы структур, совмещений и перечислений
Об"явления типов структур, совмещений и перечислений имеют ту же самую общую синтаксическую форму, как и об"явления переменных этих типов. В об"явлении типа идентификатор переменной опущен, так как нет переменной которая об"является. Именем структуры, совмещения или перечисления является тег.
В об"явлении типа может появиться список об"явлений элементов- <member-declaration-list> или список перечисления-
<enum-list>, определяющие тип.
Сокращенная форма об"явления переменной, в котором tag ссылается на тип, определенный где-то еще, при об"явлении типа не используется.
Примеры:
/******************** Example 1 ********************/
enum status {
loss = -1,
bye,
tie = 0,
win,
};
/********************* Example 2 *******************/
struct student {
char name[20];
int id, claas;
};
В первом примере об"является тип перечисления, поименованный status. Имя типа может быть использовано в об'явлениях перменных типа перечисления. Идентификатор loss явно устанавливается в -1. Идентификаторы bye и tie ассоциируются со значением 0, а win принимает значение 1. Во втором примере об"является структурный тип, поименованный student. Теперь можно использовать такое об"явление, как struct student employee, чтобы об"явить структур-
ную переменную employee типа student.
Об"явления typedef
Синтаксис:
typedef <type-spesifier><declarator>[,<declarator>...]; Об"явления typedef являются аналогом об"явления переменной,
за исключением того, что ключевое слово typedef заменяет спецификатор класса памяти.
Об"явление интерпретируется тем же самым путем, как об"явления переменной или функции, но <declarator> вместо того, чтобы стать переменной типа, специфицированного об"явлением, становится синонимом имени типа. Об"явление typedef не создает типов. Оно создает синонимы для существующих имен типов, которые были специфицированы другим способом. Любой тип может быть об"явлен с typedef, включая типы указателя, функции и массива. Имя с ключевым словом typedef для типов указателя, структуры или совмещения может быть об"явлено прежде чем эти типы будут определены, но в пределах видимости об"явления.
Примеры:
/******************** Example 1 ********************/
typedef int WHOLE;
/******************** Example 2 ********************/
typedef struct club {
char name[30];
int sise, year;
} GROUP;
/******************** Example 3 ********************/
typedef GROUP *PG;
/******************** Example 4 ********************/
typedef void DRAWE(int, int);
В первом примере об"является WHOLE как синоним для int .
Во втором примере об" является GROUP как структурный тип с тремя элементами. Так как специфицирован также тег clab, то имя GROUP и тег club могу быть использованы в об"явлениях.
В третьем примере используется предидущее имя typedef для об"явления адресного типа. Тип PG об"является как указатель на тип GROUP, который в свою очередь определен как структурный тип.
В последнем примере представлен тип DRAWE для функции не
возвращающей значения и требующей два аргумента типа int. Это означает, например, что об"явление DRAWE box; эквивалентно об"явлению void box(int, int);
Имена типов
Имя типа специфицирует особенности типа данных. Имена типов используются в трех контекстах: в списках типов аргументов, при об"явлении функций, в вычислениях cast (преобразованиях типов), и в sizeof операциях. Списки типов аргументов рассматривались в
разделе 4.5. "Об"явления функций". Преобразования cast и операция sizeof обсуждаются в разделах 5.7.2. и 5.3.4. соответственно.
Именами для основных, перечисляющих, структурных и совмещающих типов являются спецификаторы типа для каждого из них. Имена для типов указателя, массива и функции задаются следующей синтаксической формой:
<type-specifier><abstract-declarator>
Абстрактный декларатор <abstract-declarator>- это декларатор без идентификатора, состоящий из одного или более модификаторов указателей, массивов и функций. Модификатор указателя (*) всегда появляется перед идентификатором в деклараторе, в то время как модификатор массива ([]) или функции ( () ) появляются после идентификатора. Таким образом, чтобы правильно интерпретировать абстрактный декларатор, нужно начинать интерпретацию с подразумеваемого идентификатора.
Абстрактные деклираторы могут быть составными. Скобки в составном абстрактном деклараторе специфицируют порядок интерпретации, подобно тому как это делается при интерпретации составных деклараторов об"явлений. Абстрактный декларатор, состоящий из пустых круглых скобок () не допускается, поскольку это двусмысленно. В этом случае невозможно определить находится ли подразу-
меваемый идентификатор внутри скобок, и в таком случае- это немодифицированный тип, или перед скобками, тогда- это тип функции. Спецификаторы типа, установленные посредством об"явлений typedef, также рассматриваются как имена типов.
Примеры:
long * /* Example 1 */
int (*) [5] /* Example 2 */
int (*) (void) /* Example 3 */
В первом примере задано имя типа как указатель на тип long. Во втором и третьем примерах показано каким образом скобки
модифицируют составные абстрактные деклараторы. В примере 2 задано имя типа для указателя на массив иэ пяти злементов. В третьем примере именуется указатель на функцию, не требующую аргументов и возвращающую значение типа int.
КОНТРОЛЬНЫЕ ВОПРОСЫ:
1. Какие ошибки содержат следующие операторы?
enum State { on, off };
enum YesNo { yes, no};
enum DiskDriveStatus { on, off };
2. Верно или нет, что объявление следующего перечислимого типа неправильно?
enum YesNo { no = 0, No = 0, yes = 1, Yes = 1 };
3. Что не так в следующей программе?
#include <iostream.h>
int main()
{
int *p = new int;
cout << "Enter а number";
cin >> *p;
cout << "The square of " << *p << " = " << (*p * *p);
return 0;
}
Функции