C - 宏观矛盾

标签 c gcc macros c99 iso

我刚开始学习 C,我不确定一切是如何工作的。有些例子对我来说看起来很奇怪,我无法预测它会打印什么。我在 GCC 中编程,我的意思是它是我的编译器,所以我测试的每个代码都在 GCC 中。

我理解指针等所有东西是如何工作的,而且你也知道有宏。宏很奇怪,我发现了一个我没有解释的例子。例如看这段代码特定的代码:

#include <stdio.h>

int main(void){

  #define A 1

  if(A == 0){
    #define B 1
  }

  #ifdef B
    printf("B is defined, which means that A == 0.\n");
  #elif
    printf("B isn't defined, which means that A == 1.\n");
  #endif

  printf("Value of A is %d\n", A);

  return 0;
}

它应该打印什么?好吧,我虽然很容易猜到,但现在我发现这并不容易。结果不是我想的那样。

这是我的推理:我们首先定义 A1 然后如果 A0 那么定义 B1。因此,如果定义了 B,则意味着 A == 0,否则 A == 1。但是,令人惊讶的是它打印出:

B is defined, which means that A == 0.
Value of A is 1

什么?它只是打印了一个矛盾。我不确定这在 GCC 中是否有些奇怪(因为我没有 visual studio 或其他编译器来测试它)。但是,我 99% 确定我以某种方式误解了宏。我尝试使用变量而不是宏,它工作正常。

这是个问题,还是我只是误解了宏的工作原理?请记住,我是 C 初学者,所以放轻松 :)。

提前谢谢你。

最佳答案

宏是代码实际编译之前的预处理器的一部分。编译器将搜索所有预处理器指令的代码并相应地修改代码。因此,当编译器到达 if(A == 0) {#define B 1} 时,它已经扩展为 if(0 == 1) { }

宏可以轻松配置代码的某个方面或将魔数(Magic Number)替换为有意义的定义。例如:

#define DO_HOUR_CALCULATION

#define NUMBER_OF_SECONDS_PER_MINUTE (60)
#define NUMBER_OF_SECONDS_PER_HOUR (NUMBER_OF_SECONDS_PER_MINUTE * 60)
...
#ifdef DO_HOUR_CALCULATION
int hours = time / NUMBER_OF_SECONDS_PER_HOUR;
int minutes = (time % NUMBER_OF_SECONDS_PER_HOUR) / NUMBER_OF_SECONDS_PER_MINUTE;
#endif // defined(DO_TIME_CALCULATION)

另一个用途是简化重复或可配置的任务:

#define DEBUG

#ifdef DEBUG
#define DPRINTF(fmt, args...) printf(fmt, ## args)
#else
#define DPRINTF(args...)   do {} while (0)
#endif
...
ret = read(fd, p_buffer, buf_size);
DPRINTF("read(fd) returned %d\n", ret);

希望这对您有所帮助,祝您编码愉快!

关于C - 宏观矛盾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44377855/

相关文章:

c - 指向 double 组或指针数组的指针?

C 洗牌二维数组

c - fork() 在 gcc 编译器中如何运行?

c++ - GCC 和 Clang 是否优化逐字段结构复制?

c - #define with parameters...为什么这样工作?

c - 您如何告诉 Frama-C 和 Eva 入口点的参数被假定为有效?

c++ - 未使用的变量和函数的链接器错误

c++ - 在编译时识别所有调用 function1<T> 的所有 T 然后添加行 function2<T>()

c++ - Qt4中宏的继承

c - 如何根据configure文件/makefile文件删除死代码或无用代码