简体   繁体   中英

Basic C programming printf tricky

int main()
{

  printf("%d %d",1,2,3,4,5);

  return 0;
} 

output: 1,2

int main()
{
  printf("%d %d",(1,2,3,4,5));

  return 0;
}

output:5,garbage value

So please explain why is that adding brackets/parenthesis makes a difference?

It makes a difference since the , (comma) has multiple roles in C.

In the first case, it's used to separate arguments, so you call printf() with 6 arguments. More than needed, and that might be a problem in itself.

In the second case, the comma inside the parenthese is the "comma operator" , which has the effect of evaluating its left-hand side, ignoring the result, and then evaluating and returning it's right-hand side. So the expression (1,2,3,4,5) is the same as 5 . You're getting undefined behavior since you're calling printf() with the wrong number of arguments.

The parentheses change the interpretation of the comma, from just separating arguments to being the comma operator.

printf("%d %d",(1,2,3,4,5));

(1,2,3,4,5) evaluate to the last number 5 (check for the comma operator). So first output is 5 .

Second output is a rubbish number as it does not have corresponding for the second %d control string. It's typical error of mismatching control strings.

You may want to try adding another comma and now see the expected output:

printf("%d %d",(1,2,3,4,5), 7 );   // output 5, 7

In the first case you have a (variable-argument) list of function parameters. In the second case you actually have a series of the peculiar comma operator .

Meaning that the 2nd code will evaluate to the right-most operand 5 in the series of comma operators. And then, as there are no more parameters, printf() will invoke undefined behavior and crash/print garbage.

In the first example after every , there is a parameter.

In the second example the printf function is called with just 2 parameters. The format string and the result from the evaluation of the expression in brackets. The expression evaluates to the rightmost expression (look up , -operator).

But worse than that is that you do not pass the right number of parameters to the printf. The number of placeholders and the number of parameters must match, or you risk corrupting the stack.

printf() is a function that takes a variable number of arguments. Those arguments are pushed onto the stack for a function call and then read from the stack, one-by-one, as the function comes across a "%d" or "%s" or similar formatting symbol. So your first example pushes a pointer to the constant string "%d %d" and five values (1 through 5) onto the stack, and then the printf() function takes the first two of them off to print when it sees "%d %d".

printf("%d %d",1,2,3,4,5);

But your second example only pushes the string and one value. The value is 5, which is what (1,2,3,4,5) evaluates to.

printf("%d %d",(1,2,3,4,5));

As a result, your second example reads the value 5 from the stack. It then sees the second "%d" and outputs the next value that happens to be on the stack.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM