В языке "C" предусмотрена возможность, называемая TYPEDEFдля введения новых имен для типов данных. Например, описание TYPEDEF INT LENGTH; делает имя LENGTH синонимом для INT. "Тип" LENGTH может бытьиспользован в описаниях, переводов типов и т.д. Точно такимже образом, как и тип INT: LENGTH LEN, MAXLEN; LENGTH *LENGTHS[]; Аналогично описанию TYPEDEF CHAR *STRING; делает STRING синонимом для CHAR*, то есть для указателя насимволы, что затем можно использовать в описаниях вида STRING P, LINEPTR[LINES], ALLOC(); Обратите внимание, что объявляемый в конструкции TYPEDEFтип появляется в позиции имени переменной, а не сразу засловом TYPEDEF. Синтаксически конструкция TYPEDEF подобнаописаниям класса памяти EXTERN, STATIC и т. Д. мы также ис-пользовали прописные буквы, чтобы яснее выделить имена. В качестве более сложного примера мы используем конст-рукцию TYPEDEF для описания узлов дерева, рассмотренных ра-нее в этой главе: TYPEDEF STRUCT TNODE \( /* THE BASIC NODE */ CHAR *WORD; /* POINTS TO THE TEXT */ INT COUNT; /* NUMBER OF OCCURRENCES */ STRUCT TNODE *LEFT; /* LEFT CHILD */ STRUCT TNODE *RIGHT; /* RIGHT CHILD */ \) TREENODE, *TREEPTR; В результате получаем два новых ключевых слова: TREENODE(структура) и TREEPTR (указатель на структуру). Тогда функ-цию TALLOC можно записать в виде TREEPTR TALLOC() \( CHAR *ALLOC(); RETURN((TREEPTR) ALLOC(SIZEOF(TREENODE))); \) Необходимо подчеркнуть, что описание TYPEDEF не приводитк созданию нового в каком-либо смысле типа; оно только до-бавляет новое имя для некоторого существующего типа. приэтом не возникает и никакой новой семантики: описанные такимспособом переменные обладают точно теми же свойствами, что ипеременные, описанные явным образом. По существу конструкцияTYPEDEF сходна с #DEFINE за исключением того, что она интер-претируется компилятором и потому может осуществлять подста-новки текста, которые выходят за пределы возможностей мак-ропроцессора языка "C". Например, TYPEDEF INT (*PFI) (); создает тип PFI для "указателя функции, возвращающей значе-ние типа INT", который затем можно было бы использовать впрограмме сортировки из главы 5 в контексте вида PFI STRCMP, NUMCMP, SWAP; Имеются две основные причины применения описанийTYPEDEF. Первая причина связана с параметризацией программы,чтобы облегчить решение проблемы переносимости. Если для ти-пов данных, которые могут быть машинно-зависимыми, использо-вать описание TYPEDEF, то при переносе программы на другуюмашину придется изменить только эти описания. Одна из типич-ных ситуаций состоит в использовании определяемых с помощьюTYPEDEF имен для различных целых величин и в последующемподходящем выборе типов SHORT, INT и LONG для каждой имею-щейся машины.Второе назначение TYPEDEF состоит в обеспечении лучшей доку-ментации для программы - тип с именем TREEPTR может оказать-ся более удобным для восприятия, чем тип, который описантолько как указатель сложной структуры.И наконец, всегда существует вероятность, что в будущем ком-пилятор или некоторая другая программа, такая как LINT, смо-жет использовать содержащуюся в описаниях TYPEDEF информациюдля проведения некоторой дополнительной проверки программы.
* 7. Ввод и вывод *
Средства ввода/вывода не являются составной частью языка"с", так что мы не выделяли их в нашем предыдущем изложении.Однако реальные программы взаимодействуют со своей окружаю-щей средой гораздо более сложным образом, чем мы видели досих пор. В этой главе будет описана "стандартная библиотекаввода/вывода", то есть набор функций, разработанных дляобеспечения стандартной системы ввода/вывода для "с"- прог-рамм. Эти функции предназначены для удобства программногоинтерфейса, и все же отражают только те операции, которыемогут быть обеспечены на большинстве современных операцион-ных систем. Процедуры достаточно эффективны для того, чтобыпользователи редко чувствовали необходимость обойти их "радиэффективности", как бы ни была важна конкретная задача. И,наконец, эти процедуры задуманы быть "переносимыми" в томсмысле, что они должны существовать в совместимом виде налюбой системе, где имеется язык "с", и что программы, кото-рые ограничивают свои взаимодействия с системой возможностя-ми, предоставляемыми стандартной библиотекой, можно будетпереносить с одной системы на другую по существу без измене-ний. Мы здесь не будем пытаться описать всю библиотеку вво-да/вывода; мы более заинтересованы в том, чтобы продемонст-рировать сущность написания "с"-программ, которые взаимодей-ствуют со своей операционной средой.