Область действия: внешние переl 15115h71p 4;енные
Переl 15115h71p 4;енные в main line save и т.д.) являются внутреl 15115h71p 5;ними или локальными по отношению к функции main main и никакая другая функция не имеет к ним прямого доступа. Это же верно и относительно переl 15115h71p 4;енных в других функциях; например, переl 15115h71p 4;енная i getline i copy. Каждая локальная переl 15115h71p 4;енная существует только тогда, когда произошло обращение к соответствующей функции, и исчезает, как только закончится выполнение этой функции. По этой причине такие переl 15115h71p 4;енные, следуя терминологии других языков, обычно называют автоматическими. Мы впредь будем использовать термин автоматические при ссылке на эти динамические локальные переl 15115h71p 4;енные. (В главе 5 обсуждается класс статической памяти, когда локальные переl 15115h71p 4;енные все же оказываются в состоянии сохранить свои значения между обращениями к функциям).
Поскольку автоматические переl 15115h71p 4;енные появляются и исчезают вместе с обращением к функции, они не сохраняют своих значений в промежутке от одного вызова до другого, в силу чего им при каждом входе нужно явно присваивать значения. Если этого не сделать, то они будут содержать мусор.
В качестве альтернативы к автоматическим переl 15115h71p 4;енным можно определить переl 15115h71p 4;енные, которые будут внешними для всех функций, т.е. глобальными переl 15115h71p 4;енными, к которым может обратиться по имени любая функция, которая пожелает это сделать. (Этот механизм весьма сходен с COMMON в ФОРТРАНЕ и EXTERNAL в PL/1). Так как внешние переl 15115h71p 4;енные доступны всюду, их можно использовать вместо списка аргументов для передачи данных между функциями. Кроме того, поскольку внешние переl 15115h71p 4;енные существуют постоянно, а не появляются и исчезают вместе с вызываемыми функциями, они сохраняют свои значения и после того, как функции, присвоившие им эти значения, завершат свою работу.
. Внешняя переl 15115h71p 4;енная должна быть определена вне всех функций; при этом ей выделяется фактическое место в памяти. Такая переl 15115h71p 4;енная должна быть также описана в каждой функции, которая собирается ее использовать; это можно сделать либо явным описанием extern, либо неявным по контексту. Чтобы сделать обсуждение более конкретным, давайте переl 15115h71p 7;ишем программу поиска самой длинной строки, сделав line, save max внешними переl 15115h71p 4;енными. Это потребует изменения описаний и тел всех трех функций, а также обращений к ним.
define maxline // Максимальная длина строки
char line maxline // Вводимая строка
char save maxline // Самая длинная строка
int max // Длина самой длинной строки
main // Поиск длиннейшей строки: специальная версия
if max > 0 ) // Это была строка
printf( "%s", save
}
getline // Специализированная версия
line[i] = '\0'
return i
}
copy // Специализированная версия
Внешние переl 15115h71p 4;енные для функций main getline copy определены в первых строчках приведенного выше примера, которыми указывается их тип и вызывается отведение для них памяти. Синтаксически внешние описания точно такие же, как описания, которые мы использовали ранее, но так как они расположены вне функций, соответствующие переl 15115h71p 4;енные являются внешними. Чтобы функция могла использовать внешнюю переl 15115h71p 4;еную, ей надо сообщить ее имя. Один способ сделать это - включить в функцию описание extern extern
extern может быть опущено: если внешнее определение переl 15115h71p 4;енной находится в том же исходном файле, раньше ее использования в некоторой конкретной функции, то не обязательно включать описание extern для этой переl 15115h71p 4;енной в саму функцию. Описания extern main getline copy
Фактически, обычная практика заключается в помещении определений всех внешних переl 15115h71p 4;енных в начале исходного файла и последующем опускании всех описаний extern
Если программа находится в нескольких исходных файлах, и некоторая переl 15115h71p 4;енная определена, скажем в файле 1, а используется в файле 2, то чтобы связать эти два вхождения переl 15115h71p 4;енной, необходимо в файле 2 использовать описание extern
Вы должно быть заметили, что мы в этом разделе при ссылке на внешние переl 15115h71p 4;енные очень аккуратно используем слова описание и определение. «Определение» относится к тому месту, где переl 15115h71p 4;енная фактически заводится и ей выделяется память; «описание» относится к тем местам, где указывается природа переl 15115h71p 4;енной, но никакой памяти не отводится.
Между прочим, существует тенденция объявлять все, что ни попадется, внешними переl 15115h71p 4;енными, поскольку кажется, что это упрощает связи, - списки аргументов становятся короче и переl 15115h71p 4;енные всегда присутствуют, когда бы вам они ни понадобились. Но внешние переl 15115h71p 4;енные присутствуют и тогда, когда вы в них не нуждаетесь. Такой стиль программирования чреват опасностью, так как он приводит к программам, связи данных внутри которых не вполне очевидны. Переl 15115h71p 4;енные при этом могут изменяться неожиданным и даже неумышленным образом, а программы становится трудно модифицировать, когда возникает такая необходимость. Вторая версия программы поиска самой длинной строки уступает первой отчасти по этим причинам, а отчасти потому, что она лишила универсальности две весьма полезные функции, введя в них имена переl 15115h71p 4;енных, с которыми они будут манипулировать.
for getline довольно неуклюжа. Переl 15115h71p 7;ишите программу таким образом, чтобы сделать эту проверку более ясной, но сохраните при этом то же самое поведение в конце файла и при переl 15115h71p 7;олнении буфера. Является ли это поведение самым разумным?
|