I wrote the following code:

int main(){

int i=-1,j=-1,k=0,l=2,m;
m = i++ && j++ && k++ || l++;
printf("%d %d %d %d %d",i,j,k,l,m);

i=-1,j=-1,k=0,l=2,m;
m = ++i && ++j && ++k || ++l;
printf("\n%d %d %d %d %d",i,j,k,l,m);
    return(0);
}

and i got the following result:

    0 0 1 3 1

    0 -1 0 3 1

as i know postfix and prefix operators are solved after the semicolon,ie. the original values are used in the expression and then the variables resolve themselves. In that case

     i++ && j++ 

should be equal to

      ++i && ++j 

and both should be equivalent to

     i && j;
     i = i+1;
     j = j+1;

and hence the result for the two expressions must be same. but it is not so. please anyone can help me with where do i have a wrong concept.

有帮助吗?

解决方案

i++ && j++ is definitely not equivalent to ++i && ++j.

Take the case where both are zero - the first results in:

0 && j++

yielding a 0 result (and because of short-circuiting, j won't even get incremented).

In the second case, you'll get

1 && 1

yielding a 1 result.

With that in mind, let's look at your examples (spaces, semicolons and newlines added for readability):

  1. First up:

    int i = -1;
    int j = -1;
    int k =  0;
    int l =  2;
    int m = i++ && j++ && k++ || l++;
    

    Let's first parenthesize completely to make it easier to deal with:

    int m = ((i++ && j++) && k++) || l++;
    

    So, what's going to happen? First, the i++. i is incremented (and becomes 0), but because it's a post-increment, the expression's result is -1. That gives:

    int m = ((-1 && j++) && k++) || l++;
    

    Since the left side of that && is non-zero, the right side is evaluated. j++ increments j to 0, but again, post-increment means the expression's value is -1.

    int m = ((-1 && -1) && k++) || l++;
    

    Resolve that &&:

    int m = (1 && k++) || l++;
    

    Next, the right side of the remaining &&. k is incremented, becoming 1, but the expression yields 0:

    int m = (1 && 0) || l++;
    

    Resolve this &&:

    int m = 0 || l++;
    

    And finally, because the left side of the || is 0, the right side is evaluted. l is incremented, becoming 3, but as a post-increment, yields 2:

    int m = 0 || 3;
    

    Finally:

    int m = 1;
    

    And along the way we ended up with:

    i = 0;
    j = 0;
    k = 1;
    l = 3;
    

    Explaining your first printout.

  2. Next, let's look at the second example (more condensed; let me know if you want more details):

    int i = -1, j = -1, k = 0, l = 2, m;
    m = ((++i && ++j) && ++k) || ++l;   // parenthesized for readability
           ^                            // i is pre-incremented
    m = (( 0  && ++j) && ++k) || ++l;
               ^                        // first && operator short-circuits
    m = (0 && ++k) || ++l;
            ^                           // second && operator short-circuits
    m = 0 || ++l;
              ^                         // l is pre-incremented
    m = 0 || 3;
           ^                            // evaluate || operator
    m = 1;
    

    The results are:

    i =  0
    j = -1
    k =  0
    l =  3
    m =  1
    

    Exactly what you saw printed out.

其他提示

The problem is your conditional operator:

m=i++&&j++&&k++||l++;

The program will start checking the conditional statement (i++ && j++), which equates to (-1 && -1) which comes out true, therefore it continues the statement (true && k++) which means (true && 0) which is false. It will then check the OR conditional (false || l++) which means (false || 2). Each time it processed the conditional, the values were incremented via the ++ operator.

The second statement, however...

m=++i&&++j&&++k||++l;

The program started the conditional (++i && ++j) which equates to (0 && ++j). It therefore immediately saw the first condition ++i as false and immediately regarded the rest of the block(m=++i&&++j&&++k) as false, not ever processing the ++j or ++k as it did not need to, to determine that the block was going to fail. It then proceeds to the OR condition (false || ++l) or (false || 3) which is true, m=1.

In the end, the second statement only ever process ++i and ++l, leaving the others un-touched.

I would do a little research on something called "short circuiting", as it is the term that describes why this happens.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top