Основы программирования

         

Структуры и оператор определения типа typedef


Синтаксис языка Си позволяет в одном предложении определить структуру и описать несколько переменных структурного типа. Например, строка

struct R2_point { double x; double y; } t, *p;

одновременно определяет структуру R2_point (точка на двумерной плоскости) и описывает две переменные t и p. Первая имеет тип struct R2_point (точка плоскости), вторая — struct R2_point * (указатель на точку плоскости). Таким образом, после закрывающей фигурной скобки может идти необязательный список определяемых переменных, причем можно использовать все конструкции Си для построения сложных типов (указатели, массивы, функции). Список всегда завершается точкой с запятой, поэтому даже при пустом списке точка с запятой после фигурной скобки обязательна.

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

struct { double x; double y; } t, *p;

Здесь имя структуры отсутствует. Определены две переменные t и p, первая имеет структурный тип с полями x и y типа double, вторая — указатель на данный структурный тип. Такие описания в чистом виде программисты обычно не используют, гораздо чаще анонимное определение структуры комбинируют с оператором определения имени типа typedef (см. c. 117. ). Например, можно определить два типа R2Point (точка вещественной двумерной плоскости) и R2PointPtr (указатель на точку вещественной двумерной плоскости) в одном предложении, комбинируя оператор typedef с анонимным определением структуры:

typedef struct { double x; double y; } R2Point, *R2PointPtr;

Такая технология довольно популярна среди программистов и применяется в большинстве системных h-файлов. Преимущество ее состоит в том, что в дальшейшем при описании переменных структурного типа не нужно использовать ключевое слово struct, например,

R2Point a, b, c; // Описываем три точки a, b, c R2PointPtr p; // Описываем указатель на точку R2Point *q; // Эквивалентно R2PointPtr q;

Сравните с описаниями, использующими приведенное выше определение структуры R2_point:

struct R2_Point a, b, c; struct R2_Point *p; struct R2_Point *q;

Первый способ лаконичнее и нагляднее.

Вовсе не обязательно комбинировать оператор typedef непременно с анонимным определением структуры; можно в одном предложении как определить имя структуры, так и ввести новый тип. Например, предложение

typedef struct R2_point { double x; double y; } R2Point, *R2PointPtr;

определяет структуру R2_point, а также два новых типа R2Point (структура R2_point) и R2PointPtr (указатель на структуру R2_point). К сожалению, имя структуры не должно совпадать с именем типа, именно поэтому здесь в качестве имени структуры приходится использовать несколько вычурное имя R2_point. Впрочем, обычно в дальнейшем оно не нужно.

Все вышесказанное касательно языка Си справедливо и в C++. Кроме того, в C++ считается, что определение структуры S одновременно вводит и новый тип с именем S. Поэтому в случае C++ нет необходимости в использовании оператора typedef при задании структурных типов. Связано это с тем, что структура с точки зрения C++ является классом, а классы и определяемые ими типы — это основа языка C++. Сравните описания Си

struct S { ... }; struct S a, b, c; struct S *p, *q;

и C++:

struct S { ... }; S a, b, c; S *p, *q;

Конечно, описания C++ проще и нагляднее.


Содержание раздела