C препроцессор #if выражение - PullRequest
10 голосов
/ 15 июня 2011

Я немного запутался в типе выражения, которое мы можем использовать с препроцессором #IF на языке Си.Я попробовал следующий код, и он не работает.Пожалуйста, объясните и приведите примеры выражений, которые можно использовать с препроцессором.

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

int c=1;

#if c==1
    #define check(a) (a==1)?a:5
    #define TABLE_SIZE 100
#endif

int main()
{
    int a = 0, b;
    printf("a = %d\n", a);
    b = check(a);
    printf("a = %d %d\n", a, TABLE_SIZE);
    system("PAUSE");
    return 0;
}

Ответы [ 4 ]

25 голосов
/ 15 июня 2011

Препроцессор не может использовать переменные из программы на языке C в выражениях - он может работать только с макросами препроцессора.Поэтому, когда вы пытаетесь использовать c в препроцессоре, вы не получаете того, что ожидаете.

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

Поэтому, когда вы нажимаете этот фрагмент:

#if c==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif

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

#if 0==1

, что, конечно, неверно.

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

#define C 1

#if C==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif

(Обратите внимание, что я также сделал имя макроса в верхнем регистре в соответствии с соглашением для имен макросов.)

4 голосов
/ 15 июня 2011

Препроцессор запускается по тексту, прежде чем будет выполнена какая-либо компиляция.Он не знает, как проанализировать C. То, что вы, вероятно, хотели вместо int c=1;, было

#define C 1

, и тест работает так, как вы это сделали:

#if C == 1

Ключздесь все определяется до времени компиляции.Препроцессор не заботится о переменных C и, конечно, не заботится о их значениях.

Обратите внимание, что условием является использование имен макросов препроцессора, определенных в ALL_CAPS.

0 голосов
/ 15 июня 2011

В вашем примере c является сгенерированным компилятором символом, c не имеет значения до времени выполнения , тогда как выражения препроцессора оцениваются в времени сборки (фактически как следует из названия до того, как компилятор обработает код), он может работать только с символами препроцессора, которые do существуют во время сборки.

Более того, такими выражениями должны быть константы времени компиляции , или на самом деле более точно постоянная времени предварительной обработки , поскольку выражения константы компилятора, такие как, например, sizeof(...), также не определяются во время pre -переработка.

0 голосов
/ 15 июня 2011

Препроцессор не оценивает переменные Си. Он «обрабатывает» исходный код перед его компиляцией и, таким образом, имеет свой собственный язык. Вместо этого сделайте это:

#define c 1

#if c==1
#define check(a) (a==1)?a:5
#define TABLE_SIZE 100
#endif
...
...