【问题标题】:C - Output explanation of printf("%d %d\n",k=1,k=3); [duplicate]C - printf("%d %d\n",k=1,k=3); 的输出解释[复制]
【发布时间】:2017-07-09 08:24:57
【问题描述】:

如何解释以下代码的输出:

include <stdio.h>

int main(void) {
    int k;
    printf("%d %d\n",k=1,k=3);
    return 0;
}

Ideone Link

我的想法是1 将被分配给k 变量,然后1 将被打印出来。类似地,3 将分配给 k,输出将是 3

预期输出

1 3

实际输出

1 1

我在推断

int a;
if (a = 3) { 
    ...
} 

等于

if (3) { 
    ... 
}

请让我知道我哪里出错了?

【问题讨论】:

  • @CinCout 抱歉,我后来注意到了。

标签: c printf variable-assignment function-calls sequence-points


【解决方案1】:

问题是,函数参数的求值顺序没有定义,求值或参数之间没有序列点。所以,这个说法

 printf("%d %d\n",k=1,k=3)

调用undefined behavior,因为您试图多次修改同一个变量,而中间没有序列点。

一旦调用 UB 的程序运行并且(如果)有输出,无论如何都不能证明它是合理的,输出可以是任何东西。

【讨论】:

  • 没关系,一次赋值,就会打印出k的值,即3。
  • 我认为这个答案是错误的 stackoverflow.com/a/9514591/5473170 。你能检查一下吗?
  • @SurajJain 这不是最好的,但总的来说看起来不错。为什么会认为它不正确?
  • 它说的是rvalue getreturn,是不是lvalue,我不知道后面的回答这么说
  • rvalue 不是标准的 C 术语,AFAIR。它是非左值,或者更好,value of an expression
【解决方案2】:

我预计您看到 1 1 的原因是因为两个赋值语句正在发生控制被传递给 printf

printf("%d %d\n",k=1,k=3);

因此,作为对否决票的回应,是的,这是未定义的行为,因此您不应指望这种行为继续存在。然而,就确定为什么输出是1 1 而不是1 3 而言,我们可以推断3 的分配可能被1 的后续分配所阻碍。

调用 printf 时,调用堆栈包含两个条目,其中包含 k 的最终值,即 1

您可以通过将它们替换为在执行时打印某些内容的函数来测试这一点。

示例代码:

#include <stdio.h>

int test(int n) {
    printf("Test(%d)\n", n);
    return n;
}

int main(void) {
    int k;
    printf("%d %d\n",k=test(1), k=test(3));
    return 0;
}

输出:

Test(3)
Test(1)
1 1

【讨论】:

  • 这是一个很糟糕的解释,原因可能更加人为
  • @q.Thepoor 是一个温和的词,这是错误的。
  • 我真的很好奇我的解释是错误的。只是说多重赋值是UB吗?
  • I expect the reason you're seeing 1 1 is because...没有普遍的原因。所以任何一个原因,提到的都是错误的。答案(如果有的话)将非常特定于平台和环境。
  • 平心而论,我认为我在最初的答案中没有明确提到 UB。目的是推测发布者的编译器实际上做了什么,而不是语言规范要求/允许什么,但我应该更明确。
猜你喜欢
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多