typedef

Ко мне в блог регулярно приходят люди по поисковым запросам вроде «typedef», «как работает typedef» или «что такое typedef пожалуйста помогите». Ничего удивительного — написанное аршинными буквами ключевое слово языка Си в заголовке может запутать не только поисковые машины. Посему не смею больше вводить в заблуждение своих читателей, публикую небольшой ликбез на тему.

typedef — это способ создания синонима типа. Ничего сакрального при этом не происходит, и программы не приобретают никаких особых свойств. Просто иногда это позволяет несколько упростить код, освободив его от таинственных определений вроде:

void (*signal(int sig, void (*func)(int)) )(int);

Приведенная декларация является потолком сложности среди встречающихся на практике определений. Авторы книг по Си могут сколько угодно приводить примеры «массива указателей на функции, принимающих указатели на массив структур и возвращающих константный указатель на функцию, возвращающую… бла-бла-бла». Такие извращения реально встречаются в одной программе из тысячи. Да и то, при виде такого нужно усомниться во вменяемости автора.

Короче говоря, typedef используется для сокращения сложных или просто длинных определений типов, или же для сокрытия реально используемых типов, например, для облегчения портирования.

Синтаксис typedef очень прост: мы пишем обычное объявление стековой переменной и добавляем перед этим определением ключевое слово typedef. При этом никакая переменная не создается, а имя «переменной» становится синонимом указанного типа. Например:

typedef const char* string; /* string - указатель на константный символ */
typedef void (*fptr)(int); /* fptr - указатель на функцию, возвращающую void и принимающую int */

Часто можно видеть, как с помощью typedef можно избавиться от необходимости писать struct при определении переменной типа структуры:

struct s_tag {
/* какие-то члены */
};
typedef struct s_tag mystruct;
/* ... */
mystruct s;

Можно создать синоним одновременно с определением структуры:

typedef struct s_tag {
/* какие-то члены */
} mystruct;

Можно даже создать синоним для безымянной структуры:

typedef struct {
/* какие-то члены */
} mystruct;

Начинающие программисты вместо typedef часто используют препроцессор:

#define mystruct struct s_tag

Хотя со структурами вроде бы никаких проблем не возникает, использование в общем случае препроцессора для создания псевдонима типа может привести к трудноуловимым ошибкам:

#define iptr int*
iptr ptr1, ptr2; /* какой тип у ptr2? */
УжасноПлохоНормальноХорошоОтлично (18 голосов, средний: 4,22 из 5)
Loading ... Loading ...

Оставьте свой отзыв

Или введите OpenId:

XHTML: Можно использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">