【问题标题】:Printing define name c打印定义名称 c
【发布时间】:2017-04-26 12:50:35
【问题描述】:
#define Page 5

void printSystemInfo() {

printf ("%i", Page);
}

这是我的代码,谁能解释我如何在控制台中打印第 5 页?

现在我的控制台看起来像“5”但我想要“第 5 页”

感谢您的帮助!

【问题讨论】:

  • @Idos:宏不是变量!它们是完全不同的概念。
  • 符号 Page 在运行时不存在 afaik,所以不可能得到它。 可能可以在编译时对其进行字符串化,但我会质疑为什么您需要知道预处理器符号的名称。
  • @Carcigenicate:当然有一个符号“Page”。它只是在预处理器中。 (如果 C 语言甚至会使用该术语)。
  • @Olaf 在运行时?
  • printf 的文档或者你的 C 书说的不清楚呢?不要试图通过反复试验来学习 C。

标签: c printing


【解决方案1】:

您可以使用一点预处理器技巧。我们有# 运算符,它将符号转换为字符串。

#define _(a)    #a

当您调用_(foo) 时,它会将其翻译为"foo"。因此,在您的情况下,您可以执行以下操作:

#include <stdio.h>

#define _(a)    # a
#define PAGE    5

int main(int argc, char *argv[])
{
    printf("%s: %i\n", _(PAGE), PAGE);
    return 0;
}

这样做的目的是:

  1. 我们定义了一个名为_ 的宏,它接受一个参数a。该宏使用来自预处理器的运算符#(称为stringification)。这会将一个命名传递给宏的情况转换为字符串。示例:_(foo) 被转换为 "foo"

  2. main 中,printf() 调用随后被转换为printf("%s: %i\n", "PAGE", 5);。以逐步的方式,当预处理器看到_(PAGE) 符号时,它会将其转换为"PAGE"

  3. 上面的链接解释了这个东西的内部工作原理,我引用了这个链接(我的标记):

有时您可能希望将宏参数转换为字符串常量。字符串常量内的参数不会被替换,但您可以使用“#”预处理运算符。当宏参数与前导“#”一起使用时,预处理器将其替换为实际参数的文字文本,并转换为字符串常量。 与普通的参数替换不同,参数不是首先进行宏扩展的。这称为字符串化。

【讨论】:

  • 有什么原因不能传入“PAGE”吗?只是编译器强制执行它吗? (我没有投反对票)
  • 你显然没有给足够的鱼。如果没有免费的鱼,OP 将如何吃这一天?让他们挨饿简直太残忍了。 SO 社区不赞成这种行为。
  • @byxor 你是什么意思?你能详细说明一下吗?这永远不会到达编译器阶段。一切都由预处理器翻译。你可以通过gcc -E def.c 看到它是如何传递给编译器的。如果您将PAGE 直接传递给printf,预处理器会将其转换为5...所以在本例中到达编译器的是printf("%s: %i\n", "PAGE", 5);
  • 我假设预处理器是编译器的一部分。我想知道是否有任何实际理由不这样做 printf("PAGE: %i\n", PAGE);,但当我打字时,我意识到预处理器会取代它。
  • @byxor 在我看来,OP 想要一种获取宏名称的通用方法......也许是一些调试转储的东西......真的不知道......
【解决方案2】:

给你。这是非常琐碎的东西,但如果有不清楚的地方请询问。

#define Page 5

void printSystemInfo() 
{
  printf((char const[])??<0120,0141,0147,0145,0040,0045,0151,!"bad"??>,Page);
}

【讨论】:

  • 您也可以使用诸如PRINT(P,a,g,e); 之类的宏,它可以简单地实现为#define PRINT(a,b,c,d) printf((ch%:%:b%:%:r??(??))??&lt; %:a??(0??),%:b??(0??),%:c??(0??),%:d??(0??),0040,0045,0151,!%:a%&gt;,a%:%:b%:%:c%:%:d);。或者作为第三种选择,您的初级 C 编程书籍第 1 章中演示的版本。
  • 三合字母、八进制、否定和一堆乱七八糟的想象!
  • 嗯.. 八进制和废话听起来很熟悉 :)
  • @EugeneSh。简单来说,代码使用有向图而不是预处理器连接运算符,以合并预处理器标记。每个宏参数都使用 # 运算符转换为字符串,我们可以通过一些可靠的三元组访问项目 0。这然后形成所需的格式字符串,包括格式说明符,它方便地附加为八进制转义序列。该字符串由转换为字符串的a 参数的地址的逻辑否定终止。最后通过一些宏连接访问宏Page
  • 郑重声明:如果 SO 认为没有太基本的问题并且社区会拒绝关闭它们,那很好。在那种情况下,也没有太高级的答案,因为任何知识水平都可以。我的回答是正确的,并且已经过编译和测试。这个问题已经坐了1个小时了。很想编辑我的答案并将其替换为高级宏版本...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 2016-03-23
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多