Язык С




Область действия: внешние переменные - часть 2


#DEFINE MAXLINE 1000 /* MAX. INPUT LINE SIZE*/

CHAR LINE[MAXLINE]; /* INPUT LINE */ CHAR SAVE[MAXLINE];/* LONGEST LINE SAVED HERE*/ INT MAX;/*LENGTH OF LONGEST LINE SEEN SO FAR*/ MAIN() /*FIND LONGEST LINE; SPECIALIZED VERSION*/ { INT LEN; EXTERN INT MAX; EXTERN CHAR SAVE[]; MAX = 0;

WHILE ( (LEN = GETLINE()) > 0 ) IF ( LEN > MAX ) { MAX = LEN; COPY(); } IF ( MAX > 0 ) /* THERE WAS A LINE */ PRINTF( "%S", SAVE ); }

GETLINE() /* SPECIALIZED VERSION */ { INT C, I; EXTERN CHAR LINE[];

FOR (I = 0; I < MAXLINE-1

&& (C=GETCHAR()) !=EOF && C!='\N'; ++I) LINE[I] = C; ++I; } LINE[I] = '\0' RETURN(I) } COPY() /* SPECIALIZED VERSION */ { INT I; EXTERN CHAR LINE[], SAVE[];

I = 0; WHILE ((SAVE[I] = LINE[I]) !='\0') ++I; }

Внешние переменные для функций MAIN, GETLINE и COPY оп- ределены в первых строчках приведенного выше примера, кото- рыми указывается их тип и вызывается отведение для них памя- ти. синтаксически внешние описания точно такие же, как опи- сания, которые мы использовали ранее, но так как они распо- ложены вне функций, соответствующие переменные являются внешними. Чтобы функция могла использовать внешнюю переме- ную, ей надо сообщить ее имя. Один способ сделать это - включить в функцию описание EXTERN; это описание отличается от предыдущих только добавлением ключевого слова EXTERN.

В определенных ситуациях описание EXTERN может быть опу- щено: если внешнее определение переменной находится в том же исходном файле, раньше ее использования в некоторой конкрет- ной функции, то не обязательно включать описание EXTERN для этой переменной в саму функцию. Описания EXTERN в функциях MAIN, GETLINE и COPY являются, таким образом, излишними. Фактически, обычная практика заключается в помещении опреде- лений всех внешних переменных в начале исходного файла и последующем опускании всех описаний EXTERN. Если программа находится в нескольких исходных файлах, и некоторая переменная определена, скажем в файле 1, а исполь- зуется в файле 2, то чтобы связать эти два вхождения пере- менной, необходимо в файле 2 использовать описание EXTERN. Этот вопрос подробно обсуждается в главе 4. Вы должно быть заметили, что мы в этом разделе при ссыл- ке на внешние переменные очень аккуратно используем слова описание и определение. "Определение" относится к тому мес- ту, где переменная фактически заводится и ей выделяется па- мять; "описание" относится к тем местам, где указывается природа переменной, но никакой памяти не отводится. Между прочим, существует тенденция объявлять все, что ни попадется, внешними переменными, поскольку кажется, что это упрощает связи, - списки аргументов становятся короче и пе- ременные всегда присутствуют, когда бы вам они ни понадоби- лись. Но внешние переменные присутствуют и тогда, когда вы в них не нуждаетесь. Такой стиль программирования чреват опас- ностью, так как он приводит к программам, связи данных внут- ри которых не вполне очевидны. Переменные при этом могут из- меняться неожиданным и даже неумышленным образом, а програм- мы становится трудно модифицировать, когда возникает такая необходимость. Вторая версия программы поиска самой длинной строки уступает первой отчасти по этим причинам, а отчасти потому, что она лишила универсальности две весьма полезные функции, введя в них имена переменных, с которыми они будут манипулировать.

Упражнение 1-18

--------------- Проверка в операторе FOR функции GETLINE довольно неук- люжа. Перепишите программу таким образом, чтобы сделать эту проверку более ясной, но сохраните при этом то же самое по- ведение в конце файла и при переполнении буфера. Является ли это поведение самым разумным?




    Содержание  Назад  Вперед