【问题标题】:Result of Printf ("%d", &a)Printf ("%d", &a) 的结果
【发布时间】:2015-11-19 05:45:22
【问题描述】:

我有一个 C 代码。

    int a; 
    a =10;
    printf ("%d", &a); 

我想知道是否会打印一些垃圾或显示错误消息。 基本上我有兴趣了解 printf 的工作原理。它是否有表格中的变量列表之类的东西。如果有一个表,它将从那里获取 &a 的值

【问题讨论】:

  • 您的编译器对此有何评论。如果答案是“什么都没有”,那么您需要提高警告级别,或者获得更好的编译器。您的代码调用未定义的行为,因为参数列表与格式字符串不匹配。
  • 您是否尝试过运行该代码?当你做的时候你会得到什么?你问题的后半部分似乎没有任何意义。不确定变量表与printf 有什么关系。它从传递给它的参数中获取&a 的值。
  • 你为什么不用int a = 10;

标签: c


【解决方案1】:

这是一个初学者问题,值得正确回答。 (我被反对票和非建设性的 cmets 吓了一跳)

让我逐行介绍:

int a; 

第一行声明了一个名为a 的变量。该变量的类型为integer,使用普通编译器(Windows 上的 Microsoft Visual C++、Linux 上的 GCC、Mac 上的 Clang)通常为 32 位宽。整数变量是有符号的,因为您没有指定无符号。这意味着它可以表示范围从 –2,147,483,648 到 2,147,483,647 的值。

a =10;

第二行将值 10 赋给该变量

printf ("%d", &a); 

第三行是你得到令人惊讶的结果的地方。 "%d" 是“格式字符串”,它定义了作为进一步参数给出的变量如何格式化并随后打印。格式字符串由普通文本(将正常打印)和控制序列组成。控制序列以字符% 开头,以字母结尾。该字母指定预期的参数类型。 d 在上述情况下需要一个整数值。

你的代码的问题是你没有指定一个 itenger 值,你给了一个整数值的地址(使用& 运算符的地址)。正确的说法是:

printf ("%d", a);

简单。

我建议您阅读一本好的 C 书籍。我推荐来自该语言的原始作者的“C 编程语言”。您可以在amazon 上找到这本书,但您也可以在online 上找到它。

您可以在标准中找到相同的答案。但老实说,这些文件并不容易阅读。您可以找到C11 standard here 的草稿。格式选项的描述从第 309 页开始。(草稿通常足以用于编程目的,并且通常免费提供)。

【讨论】:

  • K&R 的书有点过时了。
【解决方案2】:

这是undefined behaviour

如果您是 C 新手,这可能会让您大吃一惊。然而,C 规范定义了某些程序(称为“正确程序”)的行为。如果你不遵守规范中的规则,那么你的程序是不正确的,任何事情都可能发生。上面的链接更详细。

您的程序不遵守规则,因为printf%d 格式说明符必须有一个int 类型的对应参数(在默认参数提升之后),但是您传递了一个@987654325 类型的参数@。

由于是未定义的行为,因此输出毫无意义,通常不值得研究。

【讨论】:

    【解决方案3】:

    它将打印变量'a'的地址。请记住,& 运算符返回操作数的地址。

    【讨论】:

    • 这是正确答案!上面的代码不是“未定义的行为”,它更像是“意外的行为”。
    • @BogdanWilli C 规范不同意你的观点。 §7.21.6/9 说,“如果任何参数不是相应转换规范的正确类型,则行为未定义。” 此外,许多 64 位系统具有 64 位指针,并且32 位 ints,因此将指针打印为 int 只会打印指针的一半。
    • 我已经看到你会否决我的回答。但是,Visual Studio 12.0 和 GCC 4.6.3 都同意我的观点。请阅读 microsoft 的 this page,其中声明 int 在 VS2015 上始终为 32 位。
    • @BogdanWilli 1) 在 Microsoft 编译器下,int 确实是 32 位的,但在其他环境中可能不是这样。 2) 即使int 是 32 位,指向int指针 在 64 位系统下肯定是 64 位,如果您使用 %d 格式说明符,它实际上只会打印地址的前 32 位。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多