Thread: && and || operator confusion

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    17

    && and || operator confusion

    hi,

    Can anyone explain me the results of the following program....
    insert
    Code:
    main()
    {
        int i=-3,j=2,k=0,m;
        m=++i && ++j || ++k;
        printf("%d %d %d %d",i.j,k,m);
    }
    According to my understanding

    && operation will be the first one to execute....when compared to || so....

    ++i will be -2
    and
    ++j will be 3

    since ++i and ++j are used in an expressin (&&) these two values will be incremented first and then logical && operator will be applied...Please correct me if i am wrong.

    so the result will be 0

    this 0 is logically OR'ed with ++k;

    ++k will be 1 now.(since it is used in expression)

    so

    0 || 1 will result in 1

    so the output must be....

    -2,3,1,1....but when i type the program and execute in GCC

    its giving the output

    -2,3,0,1

    I didn't understand why k is not getting incremented....

    Please give me some explanation or correct me if i am wrong.....

    Regards,
    Ram

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    C has "shortcut rules" for logical expressions. ++i is -2 (also known as "true") and ++j is 3 (also known as "true"), so ++i & ++j is "true". "true" || anything will always be true, so the right-hand side of the || doesn't happen.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    so the result will be 0
    -2 && 3 == true - where to you get the idea of 0?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by vart View Post
    -2 && 3 == true - where to you get the idea of 0?
    Probably thought that negative numbers are false.
    In C only 0 is "false" for int. Any other number is "true"

  5. #5
    Registered User
    Join Date
    Sep 2008
    Posts
    3
    Code:
    if (a>b && c>d)
    {
    e=100;
    }
    this means both have to evauluate to true for the code blocks within the expression to happen (e get the value of 100 loaded into it)

    If b is greater than a or d is greater than c the if will evalute to false and e will keep its original value.



    Code:
    if (a>b || c>d)
    {
    e=100;
    }
    Ok this one mean either one or the other has to evauluate to true

    if b is greater than a and d is actually less than c then it will result in a true result.




    Code:
    if ((!(a>b) && c<d) || a>b)
    I guess you may ask about this later. That "!" really can get confusing.

    Also as a note in your code && isnt the first to execute
    "m=++i && ++j || ++k;"
    expressions like this are done from right to left. Not left to right
    You wouldn't use logical operators like this.
    Code:
    main()
    {
        int i=-3,j=2,k=0,m;
        m=++i , ++j , ++k;
        printf("&#37;d %d %d %d",i,j,k,m);
    }
    You code returns a result but I dont think its what you want is it?
    I got -2,3,0,1 the way you did it and
    I got -2,3,1,-2 the way I did it.
    Last edited by casesensitive; 09-01-2008 at 03:34 PM.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by casesensitive View Post
    Also as a note in your code && isnt the first to execute
    "m=++i && ++j || ++k;"
    expressions like this are done from right to left. Not left to right
    You wouldn't use logical operators like this.
    It's not right to left. It's just regular operator precedence. No two operators are the same in a row, so the direction of evaluation has no bearing, except to implement the short circuit evaluation of && and ||.

    The order of evaluation is:
    1)++i
    2)check if ++j needed
    3) ++j (if needed)
    4) ++i && ++j
    5)check if ++k needed
    6)++k (if needed)
    7)(++i && ++j) || ++k
    8)m=(++i && ++j || ++k)

    Note how && and || use short circuit computation, so that the right hand side of those two is not evaluated if the final result can be deduced by the left.

    Also note that this is one of the rare cases that order of execution is well defined. For most operations, it is implementation defined whether the left hand side or right hand side get executed first.
    Code:
    main()
    {
        int i=-3,j=2,k=0,m;
        m=++i , ++j , ++k;
        printf("&#37;d %d %d %d",i,j,k,m);
    }
    You code returns a result but I dont think its what you want is it?
    Then you might as well do this:
    Code:
    int main()
    {
        int i=-3,j=2,k=0,m;
        ++i;
        m=i;
        ++j;
        ++k;
        printf("%d %d %d %d",i,j,k,m);
        return 0;
    }
    It does the same thing, but more clearly.
    Last edited by King Mir; 09-01-2008 at 03:43 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    Registered User
    Join Date
    Sep 2008
    Posts
    3
    Quote Originally Posted by King Mir View Post
    It's not right to left. It's just regular operator precedence. No two operators are the same in a row, so the direction of evaluation has no bearing, except to implement the short circuit evaluation of && and ||.

    The order of evaluation is:
    1)++i
    2)check if ++j needed
    3) ++j (if needed)
    4) ++i && ++j
    5)check if ++k needed
    6)++k (if needed)
    7)(++i && ++j) || ++k
    8)m=(++i && ++j || ++k)

    Note how && and || use short circuit computation, so that the right hand side of those two is not evaluated if the final result can be deduced by the left.

    Also note that this is one of the rare cases that order of execution is well defined. For most operations, it is implementation defined whether the left hand side or right hand side get executed first.
    Then you might as well do this:
    Code:
    int main()
    {
        int i=-3,j=2,k=0,m;
        ++i;
        m=i;
        ++j;
        ++k;
        printf("&#37;d %d %d %d",i,j,k,m);
        return 0;
    }
    It does the same thing, but more clearly.
    Yea I understand it now. I was playing with it a bit. m got assigned the result from entire expression True. 1.
    But it still gets read from right to left and || and && neither has presedance over the other.

    m is being assigned and assigments are read from right to left. from the ; until the =m
    Order of operations still exist inside the ; and = and paretheses will change his results.

    a=1 b=2 c=3 d=5

    e=a=b=c=d;
    all variables become 5
    e=d=c=b=a;
    all variables become 1


    I was a bit confused by what he was trying to do at first. My bad. Ill try to umm do right by now on.
    Last edited by casesensitive; 09-01-2008 at 04:09 PM.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by casesensitive View Post
    Yea I understand it now. I was playing with it a bit. m got assigned the result from entire expression True. 1.
    But it still gets read from right to left and || and && neither has presedance over the other.

    m is being assigned and assigments are read from right to left. from the ; until the =m
    Order of operations still exist inside the ; and = and paretheses will change his results.

    a=1 b=2 c=3 d=5

    e=a=b=c=d;
    all variables become 5
    e=d=c=b=a;
    all variables become 1


    I was a bit confused by what he was trying to do at first. My bad. Ill try to umm do right by now on.
    Assignments are evaluated from right to left, but that is only relevant when you have multiple assignments.

    But the order of execution is undefined for assignment. For example:
    Code:
    double *func1();
    int *func2();
    double func3();
    
    *func1() = *func2() = func3();
    Here is is implementation defined what order func1(), func2(), and func3() are called.
    But *func2() becomes the result of func3(), which is then assigned to *func1(). Note also that *func1() will result now store an rounded integer of what is returned by func3, even though it is of type double.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    Registered User
    Join Date
    Aug 2008
    Posts
    17

    confusion cleared

    hi,
    Thanks for everybody for solving the problem.Excellent explanation keep it up.Hats off to you guys.

    Regards,
    Rohit

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Personal Program that is making me go wtf?
    By Submeg in forum C Programming
    Replies: 20
    Last Post: 06-27-2006, 12:13 AM
  2. process killer on a loop
    By Anddos in forum Windows Programming
    Replies: 8
    Last Post: 01-11-2006, 01:50 AM
  3. Replies: 4
    Last Post: 11-23-2003, 07:15 AM
  4. Massive Function Problem
    By Marc Sharp in forum C Programming
    Replies: 10
    Last Post: 11-19-2003, 08:49 PM
  5. Tic Tac Toe Help
    By aresashura in forum C++ Programming
    Replies: 1
    Last Post: 11-21-2001, 12:52 PM