转换为字符串的运算符
Operator to convert to string
为什么代码片段 1 有效但代码片段 2 无效
代码片段 1:
#define mkstr(x) #x
int main(void)
{
printf(mkstr(abc));
return (0);
}
代码片段 2:
int main(void)
{
printf(#abc);
return(0);
}
第一个代码片段有效,因为它定义了一个 function-like 宏,您可以在其中放置任何内容,该值被正确分配为常量。
OTOH,第二个有句法错误,因为编译器不期望在 printf()
中传递的参数。因此,#
在那里毫无意义。
以#
符号开头的命令在C和C++中称为宏。宏是用该名称命名和引用的代码块。
有 2 种流行的宏类型 - Object-like 和 function-like。您使用的是 function-like 宏。
预处理器负责用实际的 object/function 调用替换宏调用。
片段 1 中的语句
#define mkstr(x) #x
上面的宏使用了一个叫做 stringizing 的特殊功能。 x
之前的 #
指定应按原样处理输入参数,即。转换为字符串常量,从而返回与传递的内容等效的字符串。
相反,当您在代码段 2 中调用以下代码时
printf(#abc);
没有任何意义。这是一个编译器错误,因为 #
不允许出现在语句的中间或结尾(请不要 #
被允许作为字符串的一部分,例如“#1”,或者用作字符字面量为 '#'
)。因此,任何以 #
开头的语句都会成为宏。
警告:不鼓励使用宏。您可以参考 Whosebug 上的 this 回答,了解为什么不使用它们。
参考以下资源以了解有关宏的更多信息
为什么代码片段 1 有效但代码片段 2 无效
代码片段 1:
#define mkstr(x) #x
int main(void)
{
printf(mkstr(abc));
return (0);
}
代码片段 2:
int main(void)
{
printf(#abc);
return(0);
}
第一个代码片段有效,因为它定义了一个 function-like 宏,您可以在其中放置任何内容,该值被正确分配为常量。
OTOH,第二个有句法错误,因为编译器不期望在 printf()
中传递的参数。因此,#
在那里毫无意义。
以#
符号开头的命令在C和C++中称为宏。宏是用该名称命名和引用的代码块。
有 2 种流行的宏类型 - Object-like 和 function-like。您使用的是 function-like 宏。
预处理器负责用实际的 object/function 调用替换宏调用。
片段 1 中的语句
#define mkstr(x) #x
上面的宏使用了一个叫做 stringizing 的特殊功能。 x
之前的 #
指定应按原样处理输入参数,即。转换为字符串常量,从而返回与传递的内容等效的字符串。
相反,当您在代码段 2 中调用以下代码时
printf(#abc);
没有任何意义。这是一个编译器错误,因为 #
不允许出现在语句的中间或结尾(请不要 #
被允许作为字符串的一部分,例如“#1”,或者用作字符字面量为 '#'
)。因此,任何以 #
开头的语句都会成为宏。
警告:不鼓励使用宏。您可以参考 Whosebug 上的 this 回答,了解为什么不使用它们。
参考以下资源以了解有关宏的更多信息