c中printf中的多个赋值语句
有人能帮我理解下面代码的输出吗c中printf中的多个赋值语句,c,compiler-construction,printf,C,Compiler Construction,Printf,有人能帮我理解下面代码的输出吗 int main() { int a=35; printf("%d %d %d %d %d",a--,a,a=20,a++,a=39); return 0; } 输出:20 19 关于如何在printf函数中用c处理(编译)赋值的深刻见解 这是未指定的行为。函数参数的求值顺序在C标准中没有指定,因此它可以以任何顺序发生 人们已经在你可以阅读的评论中给了你一些链接。但简而言之,有些东西叫做“序列点”。这样可以确保在执行之前需要执行的所有内容
int main()
{
int a=35;
printf("%d %d %d %d %d",a--,a,a=20,a++,a=39);
return 0;
}
输出:20 19
关于如何在printf函数中用c处理(编译)赋值的深刻见解 这是未指定的行为。函数参数的求值顺序在C标准中没有指定,因此它可以以任何顺序发生 人们已经在你可以阅读的评论中给了你一些链接。但简而言之,有些东西叫做“序列点”。这样可以确保在执行之前需要执行的所有内容都被执行,然后程序才能继续。在两个序列点之间,指令可以以任何顺序执行 根据C11标准: 3.4.4:
使用未指定的值,或本国际标准规定的其他行为 两种或两种以上的可能性,并且不要求在任何情况下对其进行选择 实例
a
的值
6.5.2:
如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量的值进行的值计算未排序
对象,则行为未定义。如果一个表达式的子表达式有多个允许的顺序,则如果在任何顺序中出现这种未排序的副作用,则该行为是未定义的。84)
84)他的段落呈现未定义的语句表达式,如i=++i+1代码>
a[i++]=i代码>
允许时
i=i+1代码>
a[i]=i代码>
这是未指明的行为。函数参数的求值顺序在C标准中没有指定,因此它可以以任何顺序发生
人们已经在你可以阅读的评论中给了你一些链接。但简而言之,有些东西叫做“序列点”。这样可以确保在执行之前需要执行的所有内容都被执行,然后程序才能继续。在两个序列点之间,指令可以以任何顺序执行
根据C11标准:
3.4.4:
未指定的行为
使用未指定的值,或本国际标准规定的其他行为
两种或两种以上的可能性,并且不要求在任何情况下对其进行选择
实例
示例未指定行为的一个示例是函数参数的求值顺序
6.5.2.2.10表示
在函数指示符和实际值的评估之后有一个序列点
参数,但在实际调用之前。调用函数中的每个求值(包括
其他函数调用)在
被调用函数体的执行顺序不确定
被调用函数的执行
换句话说,函数参数的求值之间没有序列点,因此可以按照编译器喜欢的顺序求值
为了完成回答,这也是未定义的行为,因为您试图在两个序列点之间多次更改a
的值
6.5.2:
如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量的值进行的值计算未排序
对象,则行为未定义。如果一个表达式的子表达式有多个允许的顺序,则如果在任何顺序中出现这种未排序的副作用,则该行为是未定义的。84)
84)他的段落呈现未定义的语句表达式,如
i=++i+1代码>
a[i++]=i代码>
允许时
i=i+1代码>
a[i]=i代码>
这是未定义的行为
这意味着程序可以打印:20 19 19 39 19
或0 0 0
甚至格式化硬盘
(C99,6.5p2)“在上一个序列点和下一个序列点之间,通过计算表达式,对象的存储值最多修改一次
当然,违反非约束的“应”表示prgram调用未定义的行为(参见C99中的4.p2)
这是未定义的行为
这意味着程序可以打印:20 19 19 39 19
或0 0 0
甚至格式化硬盘
(C99,6.5p2)“在上一个序列点和下一个序列点之间,通过计算表达式,对象的存储值最多修改一次
当然,违反非约束的“应”意味着程序调用未定义的行为(参见C99中的4.p2)。这是一个大约150万次的重复
printf("%d %d %d %d %d",a--,a,a=20,a++,a=39);