int main()
{
printf("%d %d",1,2,3,4,5);
return 0;
}
输出:1,2
int main()
{
printf("%d %d",(1,2,3,4,5));
return 0;
}
输出:5,垃圾值
那么请解释为什么添加括号/括号会有所不同?
答案 0 :(得分:9)
它有所不同,因为,
(逗号)在C中有多个角色。
在第一种情况下,它用于分隔参数,因此您使用6个参数调用printf()
。不仅仅需要,这可能本身就是一个问题。
在第二种情况下,括号内的逗号是"comma operator",其效果是评估其左侧,忽略结果,然后评估并返回它的右侧侧。因此表达式(1,2,3,4,5)
与5
相同。由于您使用错误的参数数量调用printf()
,您将获得未定义的行为。
括号改变了逗号的解释,从仅将参数分离为逗号运算符。
答案 1 :(得分:4)
printf("%d%d",(1,2,3,4,5));
(1,2,3,4,5)
计算到最后一个数字5(检查逗号运算符)。所以第一个输出是5
。
第二个输出是垃圾编号,因为它没有对应第二个%d
控制字符串。它是控制字符串不匹配的典型错误。
您可能想尝试添加另一个逗号,现在看到预期的输出:
printf("%d %d",(1,2,3,4,5), 7 ); // output 5, 7
答案 2 :(得分:3)
在第一种情况下,您有一个(变量参数)函数参数列表。在第二种情况下,你实际上有一系列奇特的comma operator。
意味着第二个代码将计算到逗号运算符系列中最右边的操作数5
。然后,由于没有更多参数,printf()将调用未定义的行为并崩溃/打印垃圾。
答案 3 :(得分:3)
在每个,
之后的第一个示例中,有一个参数。
在第二个示例中,仅使用2个参数调用printf
函数。格式字符串和括号中表达式求值的结果。表达式求值为最右边的表达式(查找,
- 运算符)。
但更糟糕的是,您没有将正确数量的参数传递给printf。占位符的数量和参数的数量必须匹配,否则您可能会损坏堆栈。
答案 4 :(得分:1)
printf()是一个接受可变数量参数的函数。这些参数被推入堆栈以进行函数调用,然后逐个从堆栈中读取,因为函数遇到了一个"%d"或"%s"或类似的格式符号。因此,您的第一个示例将指针推送到常量字符串"%d%d"并且在堆栈上有五个值(1到5),然后printf()函数在它看到"%d%d"时将其中的前两个关闭以进行打印。
printf("%d %d",1,2,3,4,5);
但是你的第二个例子只推送字符串和一个值。值为5,这是(1,2,3,4,5)计算的结果。
printf("%d %d",(1,2,3,4,5));
因此,您的第二个示例从堆栈中读取值5。然后它会看到第二个"%d"并输出恰好在堆栈上的下一个值。