我仍然在使用C语言中的宏。
所以这个应该返回-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);
}
为什么这会返回-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 :(得分:1)
override_function()
在你的情况下我将是-2,因为A是定义的但B未定义
答案 1 :(得分: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(零),则为该组 跳过它控制的指令:仅通过确定的名称处理指令 该指令是为了跟踪嵌套条件的级别;剩下的 指令的预处理标记被忽略,其他预处理标记也被忽略 组。只有控制条件评估为真(非零)的第一组是 处理。如果没有条件评估为true,并且有
#else
指令,则 由#else
控制的组被处理;缺少#else
指令,所有组 直到#endif
被跳过。
关于您的代码,
#ifdef A
为TRUE,#ifdef B
为FALSE,因此继续#else
部分,-2
包含在源代码中。#endif
。因此,在预处理之后,代码基本上看起来像
int i =-2 ;
printf("%d \n", i);
检查输出,应为-2。
按照相同的逻辑,您可以找到其他代码的预处理输出。
答案 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
条件。
答案 3 :(得分:1)
让我试着以简单的方式回答。
首先,你是对的宏有自己的逻辑,也许你了解它们是如何预处理器和所有。如果没有,那么预处理器是编译器读取的第一个代码,无论它们出现在源代码的哪个位置。
在编译器检查宏之后,就像你的情况一样,你的普通代码的某些部分对编译器来说是“不可见的”。现在让我们分析一下你的案例中隐藏或不可见代码的方式和内容。
在这种情况下,您使用的是#define A
和#define C
。这类似于布尔(但并不完全),A和B已被声明为'true'或'defined'。
然后使用#ifdef A
(#ifdef
:是if的缩写形式)这里有一个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。