预处理器如何在C中工作?

为什么以下代码16的答案是什么? 任何人都可以解释这个程序的工作吗?

#define SQUARE(n) n*n void main() { int j; j =16/SQUARE(2); printf("\nj=%d",j); getch(); } 

如果我们写下面的代码相同,那么答案是4:

 //the ans is 4 why? #include #include #define SQUARE(n) n*n void main() { int j; j =16/(SQUARE(2)); printf("\nj=%d",j); getch(); } 

你会得到

 j =16/2*2; // (16 / 2) * 2 = 16 

预处理器只是替换文本,与写入完全相同。

因此,宏调用SQUARE(2)实际上变为2*2

在你的情况下,这意味着整个表达式变为16/2 * 2,由于C的优先级规则评估为(16/2)* 2,即16。

宏应始终括在括号中,并且每个参数都包含在内。

如果我们这样做,我们得到:

 #define SQUARE(n) ((n) * (n)) 

取代为16/((2) * (2)) ,其评估为16/4,即4。

每个参数周围的parens使得像SQUARE(1+1)这样的东西按预期工作,没有它们如16/SQUARE(1+1)的调用将变为16/(1+1*1+1)这是16/3 ,即根本不是你想要的。

操作顺序。 您的表达式正在评估:

  j = 16 / 2 * 2 

等于16.制作:

 #define SQUARE(n) (n*n) 

这将迫使广场首先被评估。

您需要使用绝缘括号来定义宏,如下所示:

  #define SQUARE(n) ((n)*(n)) 

除此以外

  j = 16/SQUARE(2); 

扩展到

 j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2 

当你想要的是

 j = 16 / (2 * 2); 

1.当使用要用作表达式的宏时,应该将整个宏体括起来。

这可以防止错误的扩展,如:

 #define SQUARE(x) x*x -SQUARE(5,5) // becomes -5 * 5 

2.如果宏参数是expreessions,你也应该将它们括起来。

这可以防止出现其他类型的问题:

 #define SQUARE(x) x*x SQUARE(5+2) // becomes 5 + 2*5 + 2 

因此,正确的方法是这样写:

 #define square(n) ((n)*(n)) -SQUARE(5+2) // becomes -((5+2)*(5+2)) 

不鼓励使用宏作为函数(猜测为什么),所以请改用函数。 例如:

 inline double square(n) { return n*n; } 

宏的扩展将如下:

  j = 16/SQUARE(2); j = 16/2*2; 

等于: j = (16/2)*2; 意味着j = 16;

并且:

  j = 16/(SQUARE(2)); j = 16/(2*2); 

等于: j = 16/4; 意味着j = 4;

因为宏将扩展为:

 j = 16/2*2; 

预编译器不对扩展进行任何处理。 它将扩展的宏放在代码中。 由于您没有将替换文本括号,因此在主代码中也不会为您执行此操作。 做了 :

 #define SQUARE(n) ((n)*(n)) 

第一个示例评估为:

 16 / 2 * 2 (16 / 2) * 2 8 * 2 16 

第二个例子评估为:

 16 / (2 * 2) 16 / 4 4 

在预处理器语句中添加括号以控制操作的顺序:

 #define SQUARE(n) ((n)*(n)) 

((n)*(n))中的外括号确保在执行任何外部操作之前n是平方的。 内括号(n)确保在将表达式传递给SQUARE的情况下正确评估n,如下所示:

 16 / SQUARE(2 * 2) 16 / ((2 * 2)*(2 * 2)) 16 / (4 * 4) 16 / 16 1 
 Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro. Case 1 : result 16 define SQUARE(n) n*n void main() { int j; j =16/SQUARE(2); printf("\nj=%d",j); getch(); } its get expand as below j =16/SQUARE(2); so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n j = 16/2*2 j = (16/2)*2 j = 8*2 j =16 Case 2 : result 4 define SQUARE(n) n*n void main() { int j; j =16/(SQUARE(2)); printf("\nj=%d",j); getch(); } its get expand as below j =16/(SQUARE(2)); so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n j = 16/(2*2) j = 16/(4) j = 4 Hope this will help