An operator can be thought of as a function of its operands. Ordinarily, an operator does not modify its operands. Operators that do modify their operands are said to be ones with a side-effect. The increment/decrement (++/--) and the assignment (=) operators in C are operators which have side-effects.
Operator precedence prescribes order of evaluation of operators relative to other operators in an expresssion that has multiple operators. Associativity specifies the order in which a sequence of operators of the same precedence are evaluated. It is important to observe that these rules only prescribe the order of evaluation of operators, not the order of evaluation of operands. When only operators without side-effects are used, any order of evaluation of operands always gives the same answer. For example:
int a=1, b=1, c=1, d;
d=a*b+b*c;
In this case whether a*b is evaluated before b*c or vice-versa, the value of the expression a*b+b*c is the same.
However, when operands with side effects are used in a compound expression, order of evaluation of operands becomes important in determining the result. Here is an example:
int a=1, b=1, c;
c=b+b++;
Now, if b is evaluated before b++ the value of c becomes 2. On the other hand, if b++ is evaluated before b the value of c becomes 3.
The important point is that C does not prescribe any order in which the operands have to be evaluated. This is to allow the compiler to potentially choose one over the other to produce fast machine code. Therefore compound expressions, in which an operator with side-effects is used on an operand that also appears elsewhere in the expression, do not have a defined value and MUST BE AVOIDED. The compiler will not give an error when it sees such expression, so the programmer must exercise caution. This is also true of the assignment operator (=), which has a side-effect.