2017-01-31 3 views
4

Я только начинаю изучать C, поэтому, надеюсь, это не глупый вопрос. Проблема, с которой я сталкиваюсь, касается файлов заголовков и использования #define для констант. Я прочитал, что я должен использовать следующее, чтобы предотвратить компиляцию моего заголовка более одного раза.Использование define в файле заголовка c

#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 
. 
. //my header file content 
. 
#endif 

Я хочу, чтобы добавить константу, и я считаю, что я бы также использовать #define, такие как,

#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 

#define NUM_CONST 5 //the constant I want in my header file 
. 
. 
. 
#endif 

Как знать C, что #define NAME_OF_FILE ссылается на .h файл время #define NUM_CONST 5 - это просто константа? Это из-за значения в конце NUM_CONST? Или у меня все это совершенно неправильно?

+1

Компилятор не знает, что 'NAME_OF_FILE' является специальным. Это только особенность _convention_. Это «блокировка» файла (т. Е. Файл может быть '# include'ed несколько раз, но блокировка препятствует тому, чтобы содержимое между конструкцией блокировки и соответствующей' # endif' было прочитано компилятором более одного раза , На самом деле это препроцессор C. Если вы будете следовать логике шаг за шагом, в первый раз, '# ifndef' истинно, поэтому включено [1]' # define' и остаток. Во 2-й попытке '# ifndef' является ложным и пропускает' # endif' внизу –

ответ

3

#define IDENTIFIER определяет идентификатор для пользы от #ifdef, но то, что она определяется к является пустой строкой.

Так,

#define NAME_OF_FILE 

int main() 
{ 
    int x = NAME_OF_FILE; 
} 

разрешило бы к

int main() 
{ 
    int x = ; 
} 

Так нет "знать" участвует, только определенное, но пустой.

(Вот почему некоторые стиль руководства там рекомендуют #define NAME_OF_FILE NAME_OF_FILE, так что если NAME_OF_FILEпроисходит для использования в источнике, он заменяется-с-я препроцессором.)

+0

Отличная идея о '#define NAME_OF_FILE NAME_OF_FILE'! Я никогда не слышал об этом; есть ли у вас какая-либо ссылка на то, где он упоминается? – anatolyg

+0

@anatolyg: Это было * loooong * time (попробуйте 15 лет или около того), так как я потрудился с руководствами по стилям. Важные вещи становятся второй натурой, просто стилистические, которые вы покрываете такими инструментами, как Astyle. Это было вокруг, и я поднял его как «это не может повредить, так почему бы и нет». Не знаю, откуда я его получил. – DevSolar

4

Там нет существенной разница между двумя определяет. #define NAME_OF_FILE и #define NUM_CONST 5 - это то же самое. Они определяют замену токенов открытым текстом (в первом случае замена ничего).

Например, вы могли бы поставить последующий код:

printf("%d\n", NAME_OF_FILE NUM_CONST NAME_OF_FILE); 

и после указанных замен код будет включить, чтобы:

printf("%d\n", 5); 

, который является правильным. Нет «волшебства». Этап компиляции, который выполняет эти замены, обычно известен как «предварительная обработка».

NAME_OF_FILE не относится к файлу .h, но использование директивы ifndef позволяет не составлять один и тот же код дважды.

4

Это не так. NAME_OF_FILE может быть что угодно. У вас может быть

#ifndef PRETTY_PINK_PRINCESS 
#define PRETTY_PINK_PRINCESS 
/* definitions */ 
#endif 

И это будет работать так же хорошо. Использование NAME_OF_FILE - это просто конвенция, потому что это делает ее вероятной, что она уникальна.

0

Для компилятора оба эти заявления имеют одинаковый тип макроса

#define NAME_OF_FILE 

#define NUM_CONST 5 

То, что это построить

#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 
. 
. //my header file content 
. 
#endif 

делает, является то, что заголовок обрабатывается в первый раз, марко " NAME_OF_FILE "не определен, поэтому он определяется и обрабатывается весь контент заголовка. Во второй раз, когда компилятор обошел это, потому что заголовок был включен в проект более одного раза, заключается в том, что теперь марка определена, и заголовочный файл не обрабатывается снова. Опять же, «c-код» не знает, что у marco __TEST_H, например, есть его, потому что имя файла заголовка «test.h». Вероятно, вы, возможно, указали, что ваша IDE автоматически сгенерировала марко, после чего вы создали файл заголовка и что среда IDE назвала марко после файла для удобства пользователя. Как и еще один здесь, уже сказал, что вы можете переименовать марко (переименовать его во весь проект, я имею в виду это), и код будет компилироваться и в целом вести себя точно так же, как раньше.

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