【问题标题】:expanding macro variable within quoted string在带引号的字符串中扩展宏变量
【发布时间】:2012-06-29 05:39:12
【问题描述】:

我在两本著名的 c 书籍中发现了两种不同的东西, 第一个是 “在宏扩展中,形式参数不会在带引号的字符串中替换” - 由 K&R c 语言第 76 页

第二个是代码,

#define PRINT(var,format) printf("variable is %format\n",var)
PRINT(x_var,f);

稍后的宏调用将扩展为

printf("x_var is %f\n",x_var);
  • 这是在 ansi c - E. balagurusamy 中编程,第 448 页。

当然,两个引用相互矛盾。据我所知,第一个是真的,我的编译器给了我这样的结果。但第二本书也广为人知。我想知道以前版本的c中是否有这样的东西,或者第二次引用是错误的。

【问题讨论】:

  • 听起来您需要摆脱其中一本书。我将让您猜测要摆脱的那个是否包含该语言的发明者作为作者的那个。
  • 我更愿意给 E.Balagurusamy 一些信任 - 也许报价不准确?
  • 可能只是编辑错误。书本大小差异可以轻松实现:D

标签: c string macros c-preprocessor


【解决方案1】:

这本书是正确的。因为是时候了。我写了一个小测试程序来验证它(除非你在ed 中编程过,否则你不会欣赏文本编辑器):

#define PRINT(fmt,val) printf("val = %fmt\n", (val))
main()
{
    int x;
    x = 5;
    PRINT(d, x);
}

我在运行 Unix V6 的 PDP-11 上编译它。运行程序会产生以下输出:

x = 5

这甚至是 K&R C 之前的版本。“功能”在后来的 C 迭代之一中被删除,并在 ISO C90 中正式发布。

【讨论】:

    【解决方案2】:

    第二本书是错误的:it is easy to check 宏不会像那样展开。但是,您可以使用 # 预处理器运算符通过 stringizing 标记获得它们所描述的效果:

    #define PRINT(var,format) printf(#var" is %"#format"\n",var)
    

    现在您可以按如下方式打印变量:

    int xyz = 123;
    PRINT(xyz, d);
    

    这里是a link to a working sample on ideone

    注意在“#format”前后添加双引号,在“var”和“format”之前添加“#”。 '#' 操作符使变量的值变成一个带引号的字符串——带有它自己的双引号。这使得替换的字符串成为连续四个带引号的字符串,C 编译器将其识别为连接成一个字符串的请求。因此字符串:“xyz”、“is %”、“d”和“\n”被连接成:“xyz is %d\n”

    (请注意,此示例与原始问题中的示例不同,因为原始示例具有“变量是...”,其中答案将“变量”替换为“var”宏参数的实例)

    【讨论】:

    • 这不适用于某些格式化字符串,例如 'd 用于插入带有语言环境的逗号。我必须将宏修改如下:#define PRINT(var,format) printf(#var": "format"\n",var) ,然后在代码中将其调用为PRINT(xyz, "%'d");。这也允许我通过在 % 字符之前添加空格来分隔多行的格式。
    猜你喜欢
    • 1970-01-01
    • 2012-10-09
    • 2010-10-24
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多