2016-01-27 2 views
-1

Я все еще борется с макросами в С.Не могу обернуть мою голову вокруг Preprocessing макрокоманд

Так что это один должен вернуться -2:

#define A 
#define C 
int main() 
{ 
    int i = 
    #ifdef A 
    #ifdef B // if A AND B is defined 
     -1 
    #else // A is defined AND B is NOT defined 
     -2 
    #endif 
    #else // A is not defined 
     -3 
    #endif 
    ; 
    printf("%d \n", i); 
} 

почему isthis возвращение -3 тогда:

#define B 
#define C 
int main() 
{ 
    int i = 
    #ifdef A 
    #ifdef C 
     -1 
    #else 
     -2 
    #endif 
    #else 
     -3 
    #endif 
    ; 
    printf("%d \n", i); 
} 

Мне кажется, что у макросов есть своя логика.

+0

Вы определяете A и C. С помощью '#ifdef A' вы можете протестировать A. Или используйте '#ifndef A'to test, если он не определен. В зависимости от результата код в этой части будет скомпилирован для программы. Это часто используется в файлах заголовков, чтобы предотвратить децилерации или определения, которые будут выполняться дважды. – Flikk

+0

2nd one prints -3, потому что A больше не определен. '#ifdef C' находится внутри' #ifdef A', и он даже не будет проверен. И '# else'' #ifdef A' является '-3' – Flikk

+0

Что вы ожидаете и почему? – Olaf

ответ

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

#define A 
#define C 
int main() 
{ 
    int i = 
    #ifdef A 
    #ifdef B // if A AND B is defined 
     -1 
    #else // A is defined AND B is NOT defined 
     -2 
    #endif 
    #else // A is not defined 
     -3 
    #endif 
    ; 
    printf("%d \n", i); 
} 

в вашем случае я буду -2, так как А определяется, но B НЕ определено

+0

Спасибо. Я отредактировал свой комментарий, чтобы добавить ваши комментарии, и еще один образец, который меня смущает. –

+0

@ranpos вы не определили A, поэтому последний случай работает в обновленном вопросе. подумайте о простом, если-else, и следуйте за ответом Сурав Гоша для идентификации. тогда все будет ясно ИМО. – tigris

1

Прежде всего позвольте мне выравнивал код, соответственно, для простоты понимания.

#define A 
#define C 
int main() 
{ 
    int i = 
    #ifdef A 
     #ifdef B 
      -1 
     #else 
      -2 
     #endif 
    #else 
     -3 
    #endif 
    ; 
    printf("%d \n", i); 
} 

Теперь, в соответствии с директивой #ifdef предварительной обработки, со ссылкой на C11 стандарт, глава §6.10.1,

директивы препроцессора от форм

# ifdef identifier new-line groupopt<br> 
# ifndef identifier new-line groupopt`<br> 

проверить является ли идентификатор или в настоящее время не определено как имя макроса. [...]

Каждая директива условие проверяется в порядке. Если он оценивает значение false (ноль), группа , которую он контролирует, пропускается: директивы обрабатываются только через имя, которое определяет директиву , чтобы отслеживать уровень вложенных условностей; остальная часть токенов предварительной обработки директив 10 игнорируется, как и остальные маркеры предварительной обработки в группе . Только первая группа, состояние которой оценивается как истинное (отличное от нуля), обрабатывается . Если ни одно из условий не соответствует истинному, и существует директива #else, обрабатывается группа, контролируемая #else; отсутствует директива #else, все группы до #endif пропущены.

В отношении кода,

  • #ifdef A ИСТИНА,
  • #ifdef B ЛОЖЬ, так продолжает #else части, и -2 включен в исходный код.
  • skips до внешний #endif.

Таким образом, после предварительной обработки, код по существу выглядит

int i =-2 ; 
printf("%d \n", i); 

Проверьте вывод, он должен быть -2.

В соответствии с той же логикой вы можете узнать предварительно обработанный вывод другого кода.

1

В первом случае

int i = 
#ifdef A 
    #ifdef B // if A AND B is defined 
     -1 
    #else // A is defined AND B is NOT defined 
     -2 
    #endif 
#else // A is not defined 
    -3 
#endif 

Здесь A определяется, но B не является. Итак, будет рассмотрен последний случай else. Таким образом, выход будет -2

Принимая во внимание, во втором случае,

int i = 
#ifdef A 
    #ifdef C 
     -1 
    #else 
     -2 
    #endif 
#else 
    -3 
#endif 

C определен, но A не так снова будет идти до последнего else условия возвращения -3.

+0

для первого случая, только A и C, выход будет -2, а не -3. – tigris

+0

@tigris Спасибо за указание. Исправленный. – SKD

1

Позвольте мне попытаться ответить простым простым способом.

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

После того, как компилятор проверяет макросы, возможно, как здесь, в вашем случае, что определенная часть вашего обычного кода становится «невидимой» для компилятора. Теперь давайте проанализируем, как и что станет скрытым или невидимым кодом в вашем случае. В этом случае вы используете #define A и #define C. Это похоже на логическое (но не совсем), что A и B были объявлены «истинными» или «определенными».

Затем с #ifdef A (#ifdef: это краткая форма, если она определена) здесь есть инструкция if. Он проверяет, определено ли «A» или нет. В вашем случае A определено так, что мы переходим к следующей части, которая может рассматриваться как код внутри этого оператора if. Если бы A не были определены здесь, мы бы перешли ко второму #else // A is not defined.

Итак, теперь мы проверяем #ifdef B и нет B в вашем случае не определено, поэтому мы переходим к первому #else // A is defined AND B is NOT defined, который следует ниже. Следовательно, установка значения I--2. #endif подобен закрывающим фигурным скобкам второго оператора if. Затем мы переходим ко второму #endif, потому что A было определено, поэтому мы не переходим ко второму #else.

В итоге вы получите ответ как -2. Я проверил этот код, и он возвращает -2.

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