Объявление переменной в заголовочном файле


в случае, если у меня есть переменная, которая может быть использована в нескольких источниках - это хорошая практика, чтобы объявить его в заголовок? или лучше объявить его в .c файл и использовать extern в других файлах?

5 52

5 ответов:

вы должны объявить переменная в заголовочном файле:

extern int x;

а то определение его в один C file:

int x;

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

Вы можете (должны) объявлять его как extern в заголовочном файле, и определить его точно в 1 .файл c.

обратите внимание, что это .c файл также должен использовать заголовок и что стандартный шаблон выглядит следующим образом:

// file.h
extern int x;  // declaration

// file.c
#include "file.h"
int x = 1;    // definition and re-declaration

Если вы объявите его как

int x;

в заголовочном файле, который затем включается в несколько мест, вы получите несколько экземпляров x (и потенциально проблемы с компиляцией или связью).

правильный способ подойти к этому, чтобы иметь файл заголовка сказать

extern int x; /* declared in foo.c */

а потом в фу.c вы можете сказать

int x; /* exported in foo.h */

затем вы можете включить свой файл заголовка в любом месте, как вам нравится.

ключ должен сохранять объявления переменной в заголовочном файле и исходном файле одинаковыми.

Я использую этот трюк

------sample.c------
#define sample_c
#include sample.h

(rest of sample .c)

------sample.h------
#ifdef sample_c
#define EXTERN
#else
#define EXTERN extern
#endif

EXTERN int x;

образец.c компилируется только один раз и определяет переменные. Любой файл, который включает образец.h задается только" extern " переменной; он выделяет пространство для этой переменной.

когда вы измените тип x, он изменится для всех. Вам не нужно будет помнить, чтобы изменить его в исходном файле и заголовочный файл.

Как насчет этого решения?

#ifndef VERSION_H
#define VERSION_H

static const char SVER[] = "14.2.1";
static const char AVER[] = "1.1.0.0";

#else

extern static const char SVER[];
extern static const char AVER[];

#endif /*VERSION_H */

единственный недостаток, который я вижу, заключается в том, что Include guard не сохраняет вас, если вы включаете его дважды в один и тот же файл.