Advertisement

C++ Workshop - Expressions & Statements (Ch. 4)

Started by June 19, 2006 11:28 AM
41 comments, last by Dbproguy 16 years, 9 months ago

may i used "&" as the Logical AND instead of "&&"??

because when i try to use "&" for the logical AND, the compiler didnt give me any error and the program run properly..


thanks
Quote:
Original post by Personal_Worker

may i used "&" as the Logical AND instead of "&&"??

because when i try to use "&" for the logical AND, the compiler didnt give me any error and the program run properly..

Are you sure the program ran correctly? Can you verify that for all possible inputs?

& has multiple uses in C++. It is the address-of operator:
int x = 45;cout << &x << endl; // prints the memory location at which the contents of x are stored

It is the bitwise-AND operator:
int a = 12;    // binary: 1100int b = 9;     // binary: 1001int c = a & b; // binary: 1000

It is also used in parameter lists to indicate that a reference is expected:
int SomeFunction( SomeType & t){  ...}


It should be clear from the above that your code invoked the bitwise-AND operator instead of the logical-AND operator. Now, if your code was testing whether the result was true, it might still work for a number of inputs. Consider:
if (a && b){  ...}...if (a & b){  ...}

In C and C++, non-zero values are interpreted as "true" in boolean context, with zero or NULL values being interpreted as false. The first if statement above thus promots both a and b to boolean values (both true), then uses the logical-AND operator on the operands, yielding a result of true. The body of the if executes.

The second if statement causes the bitwise-AND to operate on a and b first, which, as we have shown earlier, can yield a non-zero and thus true value when tested in boolean context. The problem arises in cases like the following:
int a = 12; // binary: 1100int b = 3;  // binary: 0011...if (a & b) // a & b -> 1100 bitwise-AND 0011 -> 0000{  // code here does not execute}

Now, both a and b were true in boolean context, so the expectation is that the if will execute, but it doesn't. This is a subtle logic bug, and the sort of thing that can happen when you slip one operator for another, "sort of similar" one. Unfortunately we typically do this by accident and don't think to look there.


Bonus: Bitwise Operations

I mention the bitwise-AND above and speak of the results as though you should know them. C++ has four bitwise operators: bitwise-AND (&), bitwise-OR (|), bitwise-Exclusive-OR (^), more commonly referred to as XOR, and bitwise-NOT (~). Bitwise operations affect the binary representation of a numeric value bit by bit (a bit is one binary digit).
  • AND returns 1 if both operands are 1
    1 AND 1 = 11 AND 0 = 00 AND 0 = 0


  • OR returns 1 if either operand is 1
    1 OR 1 = 11 OR 0 = 10 OR 0 = 0


  • XOR returns 1 if only one of the operands is 1 (exclusively one)
    1 XOR 1 = 01 XOR 0 = 10 XOR 0 = 0


  • NOT operates on a single operand, and returns the complement
    NOT 1 = 0NOT 0 = 1


You can now see how the bitwise arithmetic was performed on a and b above by taking a bit from a and a bit in the same column from b, applying the operation and obtaining the corresponding column portion of the result.
Advertisement
thanks for the clear explanation...

but there is something still wondering me...

you have explained the difference between this

if(a && b){   statement here...}


with

if(a & b){   statement here...}


and i can get it because both a and b have its own value...


but what i still confusing is...

this..
if( (a > b) && (c < d) ){   statement here...} 


comparing with...

if( (a > b) & (c < d) ){   statement here...}


the compiler also give me no error...

i want to ask is that (a>b) and (c<d) also have its own value...???


thanks...:)
Quote:
Original post by Personal_Worker
if( (a > b) & (c < d) ){   statement here...}

the compiler also give me no error...
i want to ask is that (a>b) and (c<d) also have its own value...???
thanks...:)

Yes! The > and < operators are just like most other operators in that they return a value--true or false. False is always zero, while true is always non-zero. So in the case of (a > b) & (c < d), the < and > operators resolve first, giving two true or false values which are then binary-ANDed together to give a result. The if statement then checks this result and runs the block of code if the result is non-zero.

[Advanced]
The && operator (logical AND) also has an implementation detail in 'if' statements that you should eventually be aware of--so-called short circuit logic. For instance, in the following code:
if(foo() && bar()){  //do something}

Here, if foo() returns false (zero), then bar will never even be called, since it's impossible for the complete conditional to be true. This is something to be careful about--if bar() does something that affects your program's state, you should make sure it is called every time by moving it outside the if statement:

bool b = bar();
bool f = foo();
if(f && b)
{
//do something
}
[/Advanced]
Quote:
Original post by BeanDog
Quote:
Original post by Personal_Worker
if( (a > b) & (c < d) ){   statement here...}

the compiler also give me no error...
i want to ask is that (a>b) and (c<d) also have its own value...???
thanks...:)

Yes! The > and < operators are just like most other operators in that they return a value--true or false. False is always zero, while true is always non-zero. So in the case of (a > b) & (c < d), the < and > operators resolve first, giving two true or false values which are then binary-ANDed together to give a result. The if statement then checks this result and runs the block of code if the result is non-zero.




ok then...i already clear enough...

thanks..
Quote:
Original post by Personal_Worker
but what i still confusing is...

this..
if( (a > b) && (c < d) ){   statement here...} 


comparing with...

if( (a > b) & (c < d) ){   statement here...}


the compiler also give me no error...

i want to ask is that (a>b) and (c<d) also have its own value...???

I'm sorry, I forgot to mention that boolean values get promoted to integers in the same way that integers get promoted to booleans: true is 1 and false is 0. The expresssion
if (a > b) & (c < d))
is thus very interesting in that:
  • The boolean results of a > b and c < d are converted to integers in order for the bitwise-AND operation to occur;

  • and the integer result is converted back into a boolean in order for the if statement conditional to be evaluated.

Hope that clears up any remaining confusion.
Advertisement
On page 90, just below analysis, there is an explanation of which I think it is wrong. They probably meant to explain that there is no warning when you type a number between 10 and 100. It says "If the user types 9", but they probably meant 19 or something.
Quote:
Original post by twoaterisn
On page 90, just below analysis, there is an explanation of which I think it is wrong. They probably meant to explain that there is no warning when you type a number between 10 and 100. It says "If the user types 9", but they probably meant 19 or something.


Indeed, I think its an error.

Question :

Page 92

 if ( (x == 5 ) || (++y == 3) ) 


"If x is not equal to 5, then (++y ==3) is not evaluated. If you are couting on y to be incremented regardless, it might not happen."

Shouldnt it be : " If x IS equal to 5 " ? . If x is not equal to 5, then y will be tested to see if either one of them is true, right ? Also, if x turns out to be true, will the OR operator still check y and increment it in the process ?

Quote:
Original post by Myotis
Shouldn't it be : " If x IS equal to 5 " ? . If x is not equal to 5, then y will be tested to see if either one of them is true, right ? Also, if x turns out to be true, will the OR operator still check y and increment it in the process ?


Yes, you are correct. The || and && operators short circuit. If you need to && 2 things, if the first is false, the whole thing is false, so there is no need to test the second item. The problem is when things like this occur. You should never really do something like this, where necessary logic is skipped due to this. There are a couple cases where it could be used, but 99% of the time, it is a bug. Even in the times it is correct, there are better, more readable ways to express it.
Sean Henley [C++ Tutor]Rensselaer Polytechnic Institute
I have been messing around with operators, pre/postfix, and etc. I wrote this little code, I have no idea why it outputs the answer it does, when I do it manually into a calculator it shows a differant answer. Can someone tell me what order this is processing in?

#include <iostream>int main(){ float c = 10.143; c += --c * (c++ / --c); std::cout << c << std::endl;return 0;}


Output = 17.286
Changing C to 10.00

#include <iostream>int main(){ float c = 10.00; c += --c * (c++ / --c); std::cout << c << std::endl;return 0;}

Output = 17 (shouldnt it be 17.9 since i declare it a float?)

This topic is closed to new replies.

Advertisement