#if vs #ifndef vs #ifdef

时间:2016-05-07 19:38:57

标签: c++ c preprocessor-directive

我的问题首先是了解#ifndef#ifdef。我还想了解#if#ifndef#ifdef之间的区别。我知道#if基本上是一个if语句。例如:

#include<iostream>
#define LINUX_GRAPHICS 011x101

int main(){
 long Compare = LINUX_GRAPHICS;
 #if Compare == LINUX_GRAPHICS
   std::cout << "True" << std::endl;
 #endif
}

但其他人,虽然我读到了他们,但我无法理解。它们看似非常相似,但我怀疑它们的工作方式类似。非常感谢帮助。

5 个答案:

答案 0 :(得分:5)

public class Window { private JFrame frame; private JPanel cards; private JPanel panel1; private JPanel panel2; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Window window = new Window(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public Window() { initialize(); } private void initialize() { frame = new JFrame(); frame.setBounds(100, 100, 790, 483); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); cards = new JPanel(); cards.setLayout(new CardLayout()); panel1 = new JPanel(); panel1.setBackground(Color.BLACK); panel1.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e){ java.awt.Toolkit.getDefaultToolkit().beep(); //debug beep CardLayout cl = (CardLayout) cards.getLayout(); cl.next(cards); } }); panel2 = new JPanel(); panel2.setBackground(Color.WHITE); panel1.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e){ CardLayout cl = (CardLayout) cards.getLayout(); cl.next(cards); } }); cards.add(panel1, "panel1"); cards.add(panel2, "panel2"); frame.getContentPane().add(cards); } } 没有关于#if或其包含的值的任何概念,因此它可能不符合您的意图。

请记住预处理器可以替换纯文本。

该声明将从Compare视为

展开
#if

并正在扩展为

#if Compare == 011x101

在预处理阶段肯定不会产生#if 0 == 011x101

true#ifdef指令检查预处理程序符号是否为#ifndef d d,使用该(&lt; - )预处理程序指令,还是编译器预处理程序选项(最常见的是#define) 如果预处理程序符号带有空值或其他内容,则不关心这些。一个简单的

-D<preprocessor-symbol>

#define MY_CONDITION

足以满足

-DMY_CONDITION

展开之后的文字(或用#ifdef MY_CONDITION 隐藏)。

#ifndef声明不是预处理程序符号,也不能合理地与Compare#ifdef一起使用。

答案 1 :(得分:5)

宏由预处理器扩展,后者在运行时期间对变量值一无所知。它只是关于文本替换(或比较预处理器已知的符号)。你的行

#if Compare == LINUX_GRAPHICS

将扩展为

#if Compare == 011x101

和&#34;比较&#34;与&#34; 011x101&#34;不同,它的计算结果为false。实际上我甚至不是100%肯定,但重点是:您正在将预处理程序指令与在运行时计算的变量混合。这是无意义的。预处理程序指令不能替代C ++语句。

对于大多数传统的宏用例,现在有更好的方法。如果你真的不需要使用宏,最好不要使用它们。这使得阅读代码非常困难(例如,我不明白代码中的宏是如何工作的,除非我真的需要它,我不想知道:P)并且宏的其他问题可能导致非常困难找到程序中的错误。在使用宏之前,我建议你首先考虑是否有更自然的C ++方法来实现相同的目标。

PS:

#ifdef SYMBOL
    ifdef = "if defined"
    this part of the code is excluded before the compiler even sees it
    if SYMBOL is not defined (via #define)
#endif

#ifndef SYMBOL
    ifndef = "if not defined"
    this part of the code is excluded before the compiler even sees it
    if SYMBOL is defined (via #define)
#endif

我写了#34;排除&#34;目的是强调它对代码可读性的不良影响。如果您在正常的代码块中过度使用#ifdef#ifndef,则会非常难以阅读。

答案 2 :(得分:1)

#if是预处理器if。它只能处理预处理器的东西,它基本上是预处理器宏(函数类似或类似常量)和C代码,带有一些简单的整数文字运算。

#ifdef SOMETHING#if defined(SOMETHING)相同 #ifndef SOMETHING#if !defined(SOMETHING)相同。 defined是一个特殊的预处理程序运算符,允许您测试SOMETHING是否是已定义的宏。这些基本上是最常见用途或预处理器条件的快捷方式 - 测试是否定义了某些宏。

您可以在gcc预处理器上找到详细的手册(约80页) https://gcc.gnu.org/onlinedocs/

答案 3 :(得分:0)

Basicaly,预处理器进行文本替换。然后编译器将程序编译为机器代码。然后CPU执行机器指令。这意味着您不能使用预处理器#if而不是运算符if:一个用于文本替换,而第二个用于为CPU生成分支代码。

因此,#if#ifdef#ifndef等预处理程序指令用于基于某些“元输入”生成(一点点)不同程序的“半自动模式”。实际上,您可以自己进行这些替换,并在没有任何预处理器指令的情况下使用C / C ++程序。编译器通常还有一个命令行开关,它只输出预处理程序,即没有任何#if指令。尝试使用它,你应该得到这些指令的作用。

#ifdef XXX#if defined(XXX)相同,其中defined(XXX)内置于仅预处理程序的函数,当标识符XXX在程序文本中由另一个预处理程序指令#define定义时,该函数为true 。而#ifndef XXX只是#if !defined(XXX)

答案 4 :(得分:0)

预处理器#ifdef和#ifndef意味着followind:在您的示例中,您使用#define将名为LINUX_GRAPHICS的常量变量设置为等于011x101。所以稍后在你的程序中,你想要检查是否定义了这个变量。然后使用#ifdef,如果要检查是否定义了此变量,则使用#ifndef。我希望我能帮助你。