Для удобства синтаксиса typedef
обрабатывается как спецификатор класса хранения , например extern
, static
или register
. Семантически, конечно, все по-другому, но когда к языку добавили typedef
, было проще использовать существующий фрагмент грамматики для определения его синтаксиса.
Добавление static
к объявлению объекта не меняет смысла объявления за исключением того, что меняет класс хранения объекта на «статический» (если он еще не был):
{
int foo; /* automatic storage duration */
static int bar; /* static storage duration */
}
Замена static
на typedef
изменяет смысл объявления, так что определяемое имя - это не имя объекта, а имя типа (фактически просто псевдоним для существующего типа):
typedef int baz; /* "baz" is an alias for "int" */
Тот же синтаксис применяется к более сложным объявлениям:
int (*a)[42]; /* a is a pointer to an array of 42 ints */
static int (*b)[42]; /* Same as a, but with static storage duration */
typedef int (*c)[42] /* c is an alias for the type int(*)[42], or
"pointer to array of 42 ints" */
Как только вы поймете, что typedef
было произвольно вставлено в тот же слот в грамматике, занимаемой extern
, static
и register
, понимание объявлений typedef
не сложнее (и не проще!), Чем понимание объявлений объекта. (Программа cdecl
и веб-сайт полезны для распаковки сложных объявлений.)
Вы также можете иметь typedef
для типа функции:
void func(void); /* declare func as a function */
typedef void func_type(void); /* declare func_type as a name
for a function type */
Вы не можете использовать typedef
тип функции ed для объявления или определения функции, но вы можете использовать ее для объявления указателя на функцию:
func_type *ptr = func;
Что касается scope (имеется в виду область программного текста, в которой виден объявленный идентификатор), идентификатор, определенный объявлением typedef
, имеет ту же область, что и любой другой объявленный идентификатор. Если он объявлен в области видимости файла, вне какой-либо функции, он виден от точки объявления до конца файла. Если он объявлен внутри функции, он виден с точки, в которой он объявлен, до конца ближайшего окружающего блока. Как и любое объявление, оно может быть скрыто другим объявлением с таким же именем во внутренней области видимости.