Язык программирования Си (Ритчи, Керниган) - страница 30

Внешняя переменная должна быть определена, причем только один раз, вне текста любой функции; в этом случае ей будет выделена память. Она должна быть объявлена во всех функциях, которые хотят ею пользоваться. Объявление содержит сведения о типе переменной. Объявление может быть явным, в виде инструкции extern, или неявным, когда нужная информация получается из контекста. Чтобы конкретизировать сказанное, перепишем программу печати самой длинной строки с использованием line, longest и max в качестве внешних переменных. Это потребует изменений в вызовах, объявлениях и телах всех трех функций.

>#include ‹stdio.h›


>#define MAXLINE 1000 /* максимальный размер вводимой строки */


>int max; /* длина максимальной из просмотренных строк */

>char line[MAXLINE]; /* текущая строка */

>char longest[MAXLINE]; /* самая длинная строка */


>int getline(void);

>void copy(void);


>/* печать самой длинной строки: специализированная версия */

>main()

>{

> int len;

> extern int max;

> extern char longest[];

> max = 0;

> while ((len = getline()) › 0)

> if (len › max) {

>  max = len;

>  copy();

> }

> if (max › 0) /* была хотя бы одна строка */

>  printf("%s", longest);

> return 0;

>}


>/* getline: специализированная версия */

>int getline(void)

>{

> int c, i;

> extern char line[];

> for (i = 0; i ‹ MAXLINE-1 && (c=getchar()) != EOF && c!= '\n'; ++i)

>  line[i] = c;

> if (c == '\n') {

>  line[i]= c;

>  ++i;

> }

> line[i] = '\0';

> return i;

>}


>/* copy: специализированная версия */

>void copy(void)

>{

> int i;

> extern char line[], longest[];


> i = 0;

> while ((longest[i] = line[i]) != '\0')

>  ++i;

>}

Внешние переменные для main, getline и copy определяются в начале нашего примера, где им присваивается тип и выделяется память. Определения внешних переменных синтаксически ничем не отличаются от определения локальных переменных, но поскольку они расположены вне функций, эти переменные считаются внешними. Чтобы функция могла пользоваться внешней переменной, ей нужно прежде всего сообщить имя соответствующей переменной. Это можно сделать, например, задав объявление extern, которое по виду отличается от объявления внешней переменной только тем, что оно начинается с ключевого слова extern.

В некоторых случаях объявление extern можно опустить. Если определение внешней переменной в исходном файле расположено выше функции, где она используется, то в объявлении extern нет необходимости. Таким образом, в main, getline и copy объявления extern избыточны. Обычно определения внешних переменных располагают в начале исходного файла, и все объявления extern для них опускают.

Если же программа расположена в нескольких исходных файлах и внешняя переменная определена в