multiple '++' working in variables, and pointers

后端 未结 4 618
悲&欢浪女
悲&欢浪女 2021-01-25 20:25

This is what I think the ++ operator does

  1. a++; // a+=1 after calculating this line
  2. ++a; // a+=1 before calcuating this lin
相关标签:
4条回答
  • 2021-01-25 20:43

    See 3.2 in the C FAQ:

    3.2: Under my compiler, the code

        int i = 7;
        printf("%d\n", i++ * i++);
    

    prints 49. Regardless of the order of evaluation, shouldn't it print 56?

    A: Although the postincrement and postdecrement operators ++ and -- perform their operations after yielding the former value, the implication of "after" is often misunderstood. It is not guaranteed that an increment or decrement is performed immediately after giving up the previous value and before any other part of the expression is evaluated. It is merely guaranteed that the update will be performed sometime before the expression is considered "finished" (before the next "sequence point," in ANSI C's terminology; see question 3.8). In the example, the compiler chose to multiply the previous value by itself and to perform both increments later.

    The behavior of code which contains multiple, ambiguous side effects has always been undefined. (Loosely speaking, by "multiple, ambiguous side effects" we mean any combination of increment, decrement, and assignment operators in a single expression which causes the same object either to be modified twice or modified and then inspected. This is a rough definition; see question 3.8 for a precise one, and question 11.33 for the meaning of "undefined.") Don't even try to find out how your compiler implements such things (contrary to the ill-advised exercises in many C textbooks); as K&R wisely point out, "if you don't know how they are done on various machines, that innocence may help to protect you."

    References: K&R1 Sec. 2.12 p. 50; K&R2 Sec. 2.12 p. 54; ISO Sec. 6.3; H&S Sec. 7.12 pp. 227-9; CT&P Sec. 3.7 p. 47; PCS Sec. 9.5 pp. 120-1.

    0 讨论(0)
  • 2021-01-25 20:46

    You're not supposed to do more than one increment in arguments to a function.. because the order they can be evaluated in is ambiguous. The result of such code is undefined.

    Meaning: printf("%d,%d,%d,%d\n",a++,a++,++a,++a); Should be written as

    a++; a++;
    ++a; ++a;
    printf("%d, %d, %d, %d\n", a, a, a, a);
    

    Try and fix that first and see if the results are still confusing.

    More generally, you should only have one increment between a pair of sequence points.

    Edit: Chris is right, there's no point writing four increments in the middle of nowhere. To better answer your question: For a function void f(int) and void g(int), with int a=0,

    f(++a) = f(1);
    f(a++) = f(0);
    g(++a, ++a) = g(???); // undefined!
    

    So, increment at most once in the argument to a function.

    0 讨论(0)
  • 2021-01-25 20:56

    Don't do this. The behavior is undefined.

    From the C spec (section 6.5)...

    Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.

    Except as indicated by the syntax or otherwise specified later (for the function-call operator () , && , || , ?: , and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.

    In other words, if you update the value of a variable multiple times in the arguments for a function, you're not writing legal C code.

    0 讨论(0)
  • 2021-01-25 21:08

    It's not "per line", it's "per sequence-point" which is similar to "per expression" that the result from pre- and post- increment seem to occur.

    In fact, the increment always occurs immediately. The only variation is whether the value of the term will result in the initial or afterward value.

    To fully understand that C is not line-oriented, please refer to the standard and read the parts about "sequence points."

    Lines which begin with '#' are pre-processor input. The pre-processor for C is line-oriented, but, otherwise, C itself considers the line-break characters the same as any other white space such as tab or space.

    0 讨论(0)
提交回复
热议问题