【问题标题】:what is the difference between printf and cout [duplicate]printf和cout有什么区别[重复]
【发布时间】:2013-03-24 15:45:04
【问题描述】:

下面的一些代码:

int x = 1;
printf("%d,%d,%d",x,x++,x);  //A  statement
cout<<x<<x++<<x<<endl; //B statement

我知道执行顺序是从右到左,而为什么A语句的结果是“1,1,1” 而B语句结果为“112”???

我用的是vs2008 使用调试模式:结果相同:2,1,2。 with release mode: 结果不同:A: 1,1,1, B:1,1,2

【问题讨论】:

  • 您的问题标签很好地为您回答了整个主题。
  • 有很多不同之处。但在这两种情况下,您都在调用未定义的行为。
  • “我知道执行顺序是从右到左,” - 你呢?这很有趣,因为标准不同意。
  • @KinjalPatel:参见 C99 §7.19.3/7:“[...] 标准输入和标准输出流被完全缓冲当且仅当流可以确定不引用交互式设备。”

标签: c++ c printf cout post-increment


【解决方案1】:

您使用printf 的方式会导致未定义的行为。未指定函数参数的评估顺序。它们甚至根本不需要以谨慎的单位进行评估,因为可以评估一个表达式的一部分,然后再评估另一个表达式的一部分。这意味着如果您对评估顺序有某种依赖关系,则整个表达式可能会变得未定义。

cout 调用operator &lt;&lt; 也是如此。 &lt;&lt; 不是序列点。 cout 的不同子句的评估顺序是完全未指定的。由于您对评估具有与 printf 示例中相同类型的依赖关系,因此您也在此处调用了未定义的行为。

因此,对于这两个表达式,您可能会得到相同的结果。你可能会得到不同的结果。当您评估其中任何一个时,守护程序可能会飞出您的鼻子。你就是说不出来。

序列点和评估顺序的主题可能相当复杂。如果您想了解更多信息,我建议您看看这个问题:

【讨论】:

  • 这不是未定义的行为,它是未指定的。您的程序并未陷入未定义状态,但您可能无法获得预期的结果。
  • @EdS:是的,它是 UB——这里的逗号不是序列点(它们是函数参数分隔符,而不是逗号运算符)。
  • @AdamRosenfield:是的,我什至没有想到,我专注于参数评估顺序。我真的应该在回答 1k+ 之后看到它“为什么 x++ + ++x 不起作用?”问题。你说得对。然而,这一点是错误的 - “函数参数的评估顺序是未定义。”
  • @EdS.,未定义。我们只能确保在输入函数之前对所有参数进行了评估。
  • @EdS.,好的,我刚刚读到您提到它未指定而不是未定义。是的。我的错。
【解决方案2】:

语句A和B的结果是一样的。

        int x = 1;
        printf("%d,%d,%d",x,x++,x);  //A  statement
        //cout<<x<<x++<<x<<endl; //B statement
        return 0;

STATEMENT A

     int x = 1;
    //printf("%d,%d,%d",x,x++,x);  //A  statement
    cout<<x<<","<<x++<<","<<x<<endl; //B statement
    return 0;

STATEMENT B

结果/行为与编译器不一致。

【讨论】:

  • 结果有时是一样的。这里的使用实际上调用了未定义的行为。这意味着它可能按照您希望的方式工作,但它可能完全做其他事情。
  • 我在调试模式下使用 vs2008:结果相同:2,1,2。 with release mode: 结果不一样:A: 1,1,1, B:1,1,2
  • @guyuequan:那是因为标准没有规定正确的结果。事实上,你很幸运,你的程序没有崩溃或其他什么。
【解决方案3】:

通过this Article。 这个不错。

this 文章的重复。

但是,如果我们谈论printf()cout&lt;&lt;,技术上, 在执行printf 语句时,它会获取变量的最后一条语句更改的值,并且还会将更改的值影响到下一条语句,而不是当前语句。

虽然在cout 语句中,变量取的是最新值,所以它直接影响当前语句。

希望你能清楚。

【讨论】:

  • 虽然这在理论上可以回答问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。这也将有助于您的答案保持有用,即使您包含的链接将来会中断。
  • 这个问题的标题应该改变,因为它指的是概念问题而不是技术问题。
【解决方案4】:

使用 printf,在调用 printf 之前计算所有参数 (x=1)。 使用 cout,参数会按顺序进行评估和应用。 (至少就您的编译器而言)

【讨论】:

  • 只是为了添加更多细节 cout 是基于流的,这就是为什么要按顺序评估和应用参数。
  • 这个答案显然是错误的。
  • 已编辑以反映此特定编译的工作方式。
猜你喜欢
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 2020-08-26
  • 2017-04-18
  • 1970-01-01
  • 2017-02-17
相关资源
最近更新 更多