问题
So I am stuck with this question.
int i=5,a;
a=++i + i++ + ++i + i++ - --i;
printf("%d",a);
According to me 'a' should be 20. a=6+6+8-8 However, on execution I found the answer to be 18. What I am doing wrong? A step by step explanation would be helpful.
回答1:
This is undefined behavior. A variable cannot be changed more than once between sequence points. Your program can output anything. Any answer stating otherwise is wrong.
回答2:
I have written about this in a detailed manner in my blog post at: http://blog.susam.in/2010/05/sequence-points.html
I am posting some extracts from it here.
A particular type of question is asked time after time in C programming forums. There are two things about such questions that irritate the experienced programmers in the forums. Firstly, this type of questions is so common that many don't even want to respond to them even if it means posting a link to another thread where a similar question has been answered. Secondly, and more importantly, even if someone tries to provide the correct answer to the question, there are many others who ignore it and fill up the thread with incorrect answers.
The questions usually involve finding the output of a code like this.
#include <stdio.h>
int main()
{
int i = 5;
printf("%d %d %d\n", i, i--, ++i);
return 0;
}
The output is 5 6 5 when compiled with gcc and 6 6 6 when compiled with Microsoft C/C++ compiler that comes with Microsoft Visual Studio.
The behaviour of such C programs is undefined. In the statements printf("%d %d %d\n", i, i--, ++i); and a += a++ + a++;, semicolon is the only sequence point. C guarantees that all side effects of a given expression is completed by the next sequence point in the program. If two or more operations with side effects affecting each other occur before the next sequence point, the behavior is undefined. Such code may behave differently when compiled with different compilers.
Before I quote the relevant sections from the ISO/IEC standard, let me quote something from K&R. In Section 2.12 (Precedence and Order of Evaluation) of the book, the authors write,
C, like most languages, does not specify the order in which the
operands of an operator are evaluated. (The exceptions are &&, ||, ?:, and ','.) For example, in a statement like
x = f() + g(); f may be evaluated before g or vice versa; thus if either f or g
alters a variable on which the other depends, x can depend on the order of evaluation. Intermediate results can be stored in temporary variables to ensure a particular sequence.
They provide one more example in this section.
One unhappy situation is typified by the statement a[i] = i++; The question is whether the subscript is the old value of i or the
new. Compilers can interpret this in different ways, and generate different answers depending on their interpretation.
If you want to read more on this, download the ISO/IEC 9899 C standard and turn to page 438 for Annex C – Sequence Points. It lists down all the sequence points. ; is one of them. + and ++ operators are not sequence points.
Next, read section 5.1.2.3 (Program execution), point 2.
Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (A summary of the sequence points is given in annex C.)
回答3:
In the standard for C, it says explicitly that a compiler is free to rearrange the expression in any way so long as the precedence rules are followed. This means that if you have this expression:
x = foo() + bar() + baz()
The three functions could be called in any order and it is legal.
In older standards for C, it even said that a compiler could ignore parentheses if it wanted to:
x = (foo() + bar()) + baz()
The only sure way to force a certain order of evaluation is to use temporary variables:
temp0 = foo();
temp1 = bar();
x = temp0 + temp1 + baz();
回答4:
The expression you are assigning to a
exhibits undefined behavior, specifically the order in which the increment/decrement operations are applied to their operands.
回答5:
Depends on which order the compiler does everything in. Since it's compiler-implementation dependent, there's no "right" answer.
E.g. going strictly left->right:
a = (++i) + (i++) + (++i) + (i++) - (--i);
first second third fourth fifth
a = (6) + (6) + (8) + (8) - (7) = 21;
going right->left:
a = (++i) + (i++) + (++i) + (i++) - (--i);
fifth fourth third second first
a = 6 + 5 + 5 + 4 - 4 = 16;
来源:https://stackoverflow.com/questions/7639335/out-put-of-this-program-confused