宏"#define STR(x)#x"和"#define STR(x)VAL(x)"与"#define VAL(x)#x"之间有什么区别?

vv1*_*133 16 c

当我使用这段代码时:

#include <stdio.h>
#define STR(x) #x

int main(void)
{
    printf(__FILE__ STR(__LINE__) "hello!\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它打印

hello.c__LINE__hello!
Run Code Online (Sandbox Code Playgroud)

但是当我使用它时:

#include <stdio.h>
#define STR(x) VAL(x)
#define VAL(x) #x

int main(void)
{
    printf(__FILE__ STR(__LINE__) "hello!\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它打印

hello.c7hello!
Run Code Online (Sandbox Code Playgroud)

有什么区别

#define STR(x) #x
Run Code Online (Sandbox Code Playgroud)

#define STR(x) VAL(x)
#define VAL(x) #x
Run Code Online (Sandbox Code Playgroud)

Ant*_*ake 10

宏的参数本身是宏扩展的,除非宏参数名称出现在带有stringifier#或token-paster ##的宏体中.

在第一种情况下,STR的参数不是宏扩展的,因此您只需获取LINE宏的名称.

在第二种情况下,当STR 被转换为VAL的定义时,STR的参数宏扩展的,因此它可以工作 - 你得到实际的行号,因为LINE宏被扩展了.