基本C编程printf棘手

时间:2016-01-22 11:00:42

标签: c printf

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,垃圾值

那么请解释为什么添加括号/括号会有所不同?

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"并输出恰好在堆栈上的下一个值。