【问题标题】:Why doesn't this printf statement produce the output shown in a book example?为什么这个 printf 语句不产生书籍示例中显示的输出?
【发布时间】:2011-08-23 09:44:57
【问题描述】:
int j=5,k=9;
printf("%d...%d");

这个问题在一本书中。 给定输出:5 9 但是当我尝试这个时,我得到:垃圾值,请向我解释一下。 书中的解释说 printf 取程序前两个赋值的值

【问题讨论】:

  • 是哪本书教你的?
  • 确定这本书不是写的:printf("%d %d\n", j, k);?如果它写的和你写的完全一样,请随时停止阅读那本书和go get a better C book
  • 是的,书上写了同样的事情,我上面写的。
  • 您可能想检查该书是否有在线勘误表。

标签: c printf


【解决方案1】:

您的图书作者依赖于愚蠢的行为。 (不知道是undefined还是implementation defined还是just plain stupid。)

当调用printf(3) 时,它们会神奇地依赖于堆栈分配的jk 变量。因为printf(3) 将使用其格式字符串来确定要读取的多少个对象的类型,它会神奇地 > 将位于堆栈上的 jk 变量解释为 参数printf(3)就好像它们是故意传递给它的。 p>

这太依赖于“这一切在幕后如何运作”的魔力。除非这个代码块被“这个代码可能会告诉你......”和“永远不要做这么愚蠢的事情......”包围,否则这本书可能不值得再读了。

【讨论】:

  • +1 @sarnold 我选择了愚蠢的。这个假设可能不会成立!
  • +1 因为我最喜欢这个版本的“书很愚蠢”,因为你已经清楚地解释了这本书的例子有什么问题。就个人而言,我会将此代码称为just plain stupid。它愚蠢地依赖于代码生成器、缺乏优化器和调用约定。
  • +1 使“这本书很愚蠢”令人信服和优雅。值得一提的是,这是 UB(未能将匹配的参数编号和类型传递给 printf)。
  • @R..,我知道有人会特别知道 :) 谢谢!
【解决方案2】:

首先,如果你写

int j=5,k=9;
printf("%d...%d", j, k);

你会得到 5 9。

现在,printf 是一个可以获取可变数量参数的函数,它解析字符串,该字符串始终是第一个参数,并决定将给定参数中的值放在哪里。这意味着编译器没有强制执行给函数的参数,这就是为什么您不会收到任何错误。

如果在函数调用中将参数推入堆栈(大多数情况下),printf 将看到%d 并将下一个 int 作为数字放入堆栈(依此类推),由于除了基本字符串之外您没有分配参数,因此堆栈上的数据与函数调用无关(它是相关的,但不是您想要的:))

【讨论】:

  • 即使在一个可以工作的架构中,只有当优化器足够愚蠢地堆栈分配和初始化未引用的局部变量时才会发生这种情况。
【解决方案3】:

拿起其他书,printf("%d...%d");没有任何意义。您必须提供两个整数参数来替换格式字符串中的 %d。

【讨论】:

    【解决方案4】:

    试试:

    int j=5,k=9;
    printf("%d %d", j, k);
    

    【讨论】:

    • 我知道上面会打印答案。但事实并非如此。
    • 这样的话,给自己找一块大石头,一根绳子,把石头绑在书上,然后扔进一个很深的湖里;)
    猜你喜欢
    • 2018-02-27
    • 2017-01-03
    • 2023-01-02
    • 1970-01-01
    • 2020-07-28
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多