【问题标题】:Macro behavior in function函数中的宏行为
【发布时间】:2015-10-01 15:25:13
【问题描述】:

我预计以下程序的输出为 10 20,但它是 10 10。

#include <stdio.h>
#define i 10

int main()
{
printf("%d\t",i);
fun();
printf("%d",i);
return 0;
}

fun(){
    #undef i
    #define i 20
}

如果我假设如果函数调用 fun() 返回到 main() 那么原始的 i 值会被打印出来,然后通过查看下面程序的输出我错了,

#include <stdio.h>
#define i 10

fun(){
    #undef i
    #define i 20
}

int main()
{
printf("%d\t",i);
fun();
printf("%d",i);
return 0;
}

预期输出:10 20 但输出为:20 20

谁能解释一下我的行为?

【问题讨论】:

  • 线索在处理宏的组件的名称中:pre-处理器:宏在编译期间被扩展,而不是在运行时

标签: c function macros c-preprocessor


【解决方案1】:

#define 是一个预处理器宏。该值在编译时而不是运行时被替换。

因此,处理是根据#defines 的存在(顺序)进行的。这意味着,您不能期望 #undef#define 在运行时工作。

详细说明,您的案例 1 代码如下所示

#include <stdio.h>
#define i 10

int main()
{
printf("%d\t",10);
fun();
printf("%d",10);
return 0;
}

fun(){
    #undef i
    #define i 20
}//now i is 20, but no one is using it, at compile time

而且,您的第二个代码看起来像

#include <stdio.h>
#define i 10

fun(){
    #undef i
    #define i 20   // i get a new definition here
}

int main()
{
printf("%d\t",20);
fun();
printf("%d",20);
return 0;
}

注意:main() 的推荐签名是int main(void)

【讨论】:

  • 如果是这种情况,在第一个程序编译代码时,为什么 "i" 的值没有变成 20 ?在编译时函数“fun”也被评估了吗?
  • @vidya 不要忘记,该函数在运行时被“调用”。在编译时,它只是源代码,没有别的。 :-)
  • @SouravGhosh:我认为 OP 对他的第二个 sn-p 将宏 i 重新定义为 20 感到困惑,即使 #define 位于函数体内
  • @EliasVanOotegem 我明白了,但是如何更好地表达呢?您能提出一些可以消除任何困惑的建议吗?
  • @SouravGhosh:也许是一个善意的谎言:OP 可以将预处理器视为解释器(如 bash 或其他东西):它从上到下工作,替换它遇到时知道的所有宏他们。如果再次定义现有宏,它将用它知道的最新定义替换所有后续出现(LiFo 扩展类的东西)。只是抛出一些类比/建议,希望可以为 OP 澄清这一点......
【解决方案2】:

编译时的第一步是将所有 PREPROCESSING TOKENS 替换为它们的值。所以评估是在编译时完成的,而不是在运行时。

所以你得到的第一个例子是:

#include <stdio.h>

int main()
{
  printf("%d\t",10); // we have only seen define i 10 until now
  fun();
  printf("%d",10); // we have only seen define i 10 until now
  return 0;
}

fun(){
  // the two in here would have made any i after this location be replaced with 20
}

你的第二种情况也类似。

【讨论】:

    猜你喜欢
    • 2018-11-19
    • 1970-01-01
    • 2020-07-20
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多