Часто в этих определениях используются прописные буквы, чтобы напомнить пользователю, что имя типа является на самом деле символической аббревиатурой:
typedef float REAL;
В последнем примере можно было бы применить директиву #define. А здесь это делать нельзя:
typedef char *STRING;
Без ключевого слова typedef оператор определял бы STRING как указатель на тип char. С ключевым словом оператор делает STRING идентификатором указателей на тип char. Так,
STRING name, sign;
означает
char *name, *sign;
Мы можем использовать typedef и для структур. Вот пример:
typedef struct COMPLEX {
float real;
float imag; };
Кроме того, можно использовать тип COMPLEX для представления комплексных чисел.
Одна из причин использования typedef заключается в создании удобных, распознаваемых имен для часто встречающихся типов. Например, многие пользователи предпочитают применять STRING или его эквивалент, как это мы делали выше. Вторая причина: имена typedef часто используются для сложных типов. Например, описание
typedef char *FRPTC ( ) [5];
приводит к тому, что FRPTC объявляет тип, являющийся функцией, которая возвращает указатель на пятиэлементный массив типа char. (См. "Причудливые описания".)
Третья причина использования typedef заключается в том, чтобы сделать программы более мобильными. Предположим, например, что вашей программе нужно использовать 16-разрядные числа. В некоторых системах это был бы тип short, в других же он может быть типом int. Если вы использовали в ваших описаниях short или int, то должны изменить все описания, когда перейдете от одной системы к другой. Вместо этого сделайте следующее, В файле директивы #include есть такое определение:
typedef short TWOBYTE;
Используйте TWOBYTE в ваших программах для переменных типа short,
которые должны быть 16-разрядными. Тогда если вы перемешаете программу туда, где необходимо использовать тип int, то следует только изменить одно определение в вашем файле директивы #include:
typedef int TWOBYTE;
Это пример того, что делает язык Си столь мобильным. При использовании typedеf следует иметь в виду, что он не создаст новых типов, он только создает удобные метки.
ПРИЧУДЛИВЫЕ ОПИСАНИЯ
| Модификатор | значение | ||
|---|---|---|---|
| * | указатель | ||
| ( ) | функция | ||
| [ ] | массив |
int board[8] [8]; /* массив массивов типа int */
int **ptr; /* указатель на указатель на тип int */
int *risks[10]; /* 10-элементный массив указателей на тип int */
int (*wisks) [10]; /* указатель на 10-элемснтный массив типа int */
int *oof[3] [4]: /* 3-элементныи массив указателей на 4-элементный
массив типа int */
int (*uuf) [3][4]; /* указатель на массив 3х4 типа int */
Для распутывания этих описаний нужно понять, в каком порядке следует применять модификаторы. Три правила помогут вам справиться с этим.
1. Чем ближе кодификатор стоит к идентификатору, тем выше его приоритет.
2. Модификатиры [ ] и ( ) имеют приоритет выше, чем *.
3. Круглые скобки используются для объединения частей выражения, имеющих самый высокий приоритет.
Давайте применим эти правила к описанию int *oof[3] [4];
* и [3] примыкают к oof и имеют более высокий приоритет, чем [4] (правило 1). [3] имеет приоритет более высокий, чем * (правило 2). Следовательно, oof является 3-элементным массивом (перпый МОДИФИКАТОР) указателей (второй модификатор) на 4-элементный массив (третий модификатор) типа int (описание типа).
В описании
int (*uuf)[3][4];
скобки говорят, что модификатор * должен иметь первый приоритет, а это делает uuf указателем, как показано в предыдущем описании. Эти правила создают также следующие типы:
char *fump( ); /* функция, возвращающая указатель на тип char */
char (*frump) ( ); /* указатель на функцию, возвращающую тип char */
char *flump ( ) [3] /* функция, возвращающая указатель на 3-элементный
массив типа char */
char *flimp[3] ( ) /* 3-элементный массив указателей на функцию, которая
возвращает тип char */
Если вы примените структуры к этим примерам, то увидите, что возможности для описаний действительно растут причудливо. А применения ... так и быть, МЫ оставим их для более опытных программистов.
Язык Си со структурами, объединениями и typedef дает нам средства для эффективной и мобильной обработки данных.
ЧТО ВЫ ДОЛЖНЫ БЫЛИ УЗНАТЬ В ЭТОЙ ГЛАВЕ
Что такое имя структуры и как оно используется
Как определить структурную
переменную: struct car honda;
Как обратиться к элементу структуры: honda.mpg
Как обратиться к указателю на структуру: struct car *ptcar;
Как обратиться к элементу при помощи указателя: ptcar->mpg
Как передать в функцию элемент структуры: eval(honda.mpg)
Как сообщить функции о структуре: rate(&honda)
Как создать вложенную структуру
Как обратиться к элементу вложенной структуры: honda.civic.cost
Как создавать и использовать массивы структур: struct car gm[5];
Как создать объединение: подобно структуре