2015-07-07 2 views
3

Я пытаюсь изучить C, используя this учебник. Существует пример того, что автор пытается узнать нас, что такое класс хранения static.Почему глобальная переменная определяется как статическая в этой программе?

Это тот пример:

#include <stdio.h> 

/* function declaration */ 
void func(void); 

static int count = 5; /* global variable */ 

main() 
{ 
    while(count--) 
    { 
     func(); 
    } 
    return 0; 
} 
/* function definition */ 
void func(void) 
{ 
    static int i = 5; /* local static variable */ 
    i++; 

    printf("i is %d and count is %d\n", i, count); 
} 

Мой вопрос: Почему он/она определяется count как static? Другими словами, в чем разница между вышеуказанной программой и следующей программой?

#include <stdio.h> 

/* function declaration */ 
void func(void); 

int count = 5; /* global variable */ 

main() 
{ 
    while(count--) 
    { 
     func(); 
    } 
    return 0; 
} 
/* function definition */ 
void func(void) 
{ 
    static int i = 5; /* local static variable */ 
    i++; 

    printf("i is %d and count is %d\n", i, count); 
} 

Я имею в виду, когда мы должны использовать первую программу, и когда мы должны использовать второй?

+3

http://stackoverflow.com/a/4725234/3049655 –

+0

Вы также должны * читать код * например, изучите исходный код * существующего бесплатного программного обеспечения *. –

ответ

4

Определения вашего count как глобальный переменные или static один не имеет значения в вашем конкретном примере (где каждая программа имеет только один исходный файл, то есть один translation unit). Но это имеет значение для i (который без ключевого слова static станет автоматической локальной переменной), так как объявлено внутри функция. Однако для любой программы, состоящей из нескольких единиц перевода (связанных друг с другом для создания исполняемого файла), это будет иметь большое значение.

Если определить глобальную переменную count в двух разных единицах трансляции (т.е. в foo1.c и foo2.c) компоновщик пожалуется на несколько определений (когда вы строите свой foo исполняемый файл из foo1.o & foo2.o с gcc foo1.o foo2.o -o foo в вашей системе Linux); если вы определили переменную static int count; как в , так и в foo2.c это нормально (но тогда у вас есть две синонимичные переменные, каждый из которых имеет свой собственный адрес и каждый неявно инициализирован до 0; ИМХО это часто плохой вкус, поскольку он делает исходный код менее читабельный).

В качестве исключения вы можете объявить без явной инициализации его глобальной переменной с тем же именем в двух разных единицах перевода. Название относится к тем же и уникальным глобальным (инициализируется 0).

Так наличие

// in file foo1.c 
int globalcount; // a global variable *declaration* 

и

// in file foo2.c 
int globalcount; // a global variable *declaration* 

такое же, как имеющий

// in file foo1.c 
int globalcount = 0; // a global variable *definition* with initialization 

и

// in file foo2.c 
extern int globalcount; // an external variable declaration 

Собственно, эта внешняя декларация обычно должна быть в каком-то заголовочном файле foo.h, который получает #include -d обоими foo1.c & foo2.c.

Следовательно, статические переменные (основной программы) также невидимы plugins. Узнайте больше о visibility attribute (в Linux), чтобы сделать переменную видимой только одним плагином или разделяемой библиотекой (но не за ее пределами).

Читать вики страницы на linkers & dynamic linkers тогда книга Левина linkers and loaders

Практически говоря, я бы предложил использовать уникальные имена для нелокального переменных (как глобальных и статических), для удобства чтения и удобства (так как легко до grep); но иногда вам может понадобиться несколько переменных static с тем же именем в разных единицах компиляции. Если вы это сделаете, я предлагаю прокомментировать, почему, и имеют некоторые последовательные соглашения об именах.

Посмотрите примеры в некоторых free software закодированных в С.

+0

Спасибо за этот полный ответ. Что произойдет, если я определю 'int count' в foo1.c и' static int count = 5' в foo2.c? –

+1

Затем в 'foo2.c' вы увидите статическую переменную. Но вы не должны кодировать этот путь (это запутывает для человеческих разработчиков и делает ваш код нечитаемым) –

+0

Я думаю, что ваш ответ требует небольшой доработки. Здесь: _... если вы определили 'static int count;' переменные both ..._, я думаю, что я должен инициализировать статическую переменную в точке определений. правильно? –

3

static для глобальной переменной делает его глобальным только для этого файла (блок компиляции). Он не будет доступен из других файлов (единицы компиляции)

Смежные вопросы