It is a very rare program that solves a problem with the exact same sequence of operations every time it is executed. What is more common is a program that does some operations if the data or user inputs look a certain way, and a different set of operations if the data look a different way.
The way we can do this in C++ is with “conditionals.” The word “conditional” means that some operations will only occur if a certain “condition” is true.
For example, consider the program that gives the user three attempts to guess a number between 1 and 10. Here is what the program should do (in pseudo-code):
- Ask the user for the first guess. Save this guess into a variable called
guess1is the correct guess, then tell the user “Success!” and quit.
guess1is not the correct guess, then tell the user “Nope. Try another guess.” and save the second guess into a variable called
guess2is the correct guess, then tell the user “Success!” and quit.
guess2is not the correct guess, then tell the user “Nope. Try another guess.” and save the third guess into a variable called
guess3is the correct guess, then tell the user “Success!” and quit.
guess3is not the correct guess, then tell the user “Nope. You are not allowed any more guesses, sorry! The number you failed to guess was [the number].” (where “the number” is the real number).
How to do it in code
In C++, we have a command called
if. This is what it looks like:
Of course, we need to change the phrase
...something... to a “conditional.”
The if command expects something that results in a
bool value. So we can use
bool values like
But these conditionals (
false) are not very interesting because in
the first case, the stuff inside the
if block will always be executed (a
“block” is the stuff between
}). In the second case, the stuff in the
block will never be executed.
More interesting conditionals may involve the following boolean operators
bool variables and
x is an
!p– “not p” or “opposite of the value that p has”
p || q– “p or q”
p && q– “p and q”
x == 5– “the value in the variable x is equal to 5”
x != 5– “the value in the variable x is not equal to 5”
x < 5
x > 5
x <= 5– “the value in the variable x is less than or equal to 5”
x >= 5
(x >= 0) && (x <= 5)– “x is between 0 and 5” (x can be one of [0,1,2,3,4,5]); note that you cannot say
(0 <= x <= 5)(wrong!)
So we can write our guessing program like this:
if we can also use
else to specify some operations that should be
executed if the conditional is not satisfied. Example:
if commands can be inside other
Series of if/else’s
It is common practice to check a series of conditions, where you only expect one of them to be true:
An example of nested if’s and an if/else-if chain
Task: Write a program that asks for three decimal numbers (a, b, c) and
prints a message indicating whether the quadratic equation ax^2 + bx + c = 0 has no
solutions, one solution, two solutions, or no real solutions (i.e., only
imaginary solutions). Your program will need to make use of several
statements. Nest the
if statements appropriately so that you do not test for a
condition twice (e.g., you must check if a equals 0 only once, not five
times). Here is the algorithm:
- If a equals 0 and b equals 0, then there is no solution (output “No solution.”).
- If a equals 0 and b does not equal 0, then there is one solution: x = -c/b.
- If a does not equal 0 and b^2 - 4ac equals 0, then there is one solution: x = -b/(2a).
- If a does not equal 0 and b^2 - 4ac is greater than 0, then there are two solutions: x = (-b - √(d))/(2a) and x = (-b + √(d))/(2a).
- If a does not equal 0 and b^2 - 4ac is less than 0, then there are no real solutions, i.e. two imaginary solutions.
Enter value 'a': 0 Enter value 'b': 0 Enter value 'c': 7 No solution. Enter value 'a': 0 Enter value 'b': 0.5 Enter value 'c': 2 x = -4 Enter value 'a': 1 Enter value 'b': -6 Enter value 'c': 9 x = 3 Enter value 'a': 1 Enter value 'b': -3 Enter value 'c': 2 x = 1 OR x = 2 Enter value 'a': 1 Enter value 'b': 0 Enter value 'c': 1 No real solution.
An alternative series of if/else’s is the
switch statement. The
switch statement is the same as a series of if/else’s because only
one of the conditions should turn out to be true. The
statement can only handle simple conditions, however; actually, it can
only handle conditions of the form “is some integer equal to some
value?” This means that a
switch statement can only be used for
Here is an example.
switch statement above can be rewritten with a series of if/else’s:
Notice that an
if is much more powerful: you can use very
complicated conditionals. On the other hand, a
switch is very
simple: for each “case”, you provide a value that is compared to the
variable used in the switch (in this case, the variable used in the
switch is “number”). Each case basically asks, “does the value in the
variable equal this number?”
Each “case” in a
switch needs a “break” at the end so that the next
case is not entered. It’s good practice to always include a “break” at
the end of each case in a
The “default” case is the case that is used if all the other cases fail.
You can also use a
switch to determine which character a user typed,
since characters are themselves just integers. Here is an example:
Another view of the “if” construct
It turns out that, in C and C++, any integer that’s not zero is considered a “true” value, and zero is considered the singular “false” value. Thus, these are equivalent:
Actually, the details are more gruesome than this. So it’s best to avoid such trickery.
if conj. 1 (Poetic) Kiplingian milestones on the road to mandelayhood and gambler’s ruin. 2 (CS) One of many conditional control-flow obstacles faced by a process linearly anxious to complete the next instruction without tiresome, trivial, testing diversions.
Some programmers see
ifas the soul of machine intelligence. Thus,
forms the core of many a smart, ethical money manager. The home-exit loving, non-judgmental process, however, reluctantly forced to test transient bits of registers, is tempted to rule in favor of
else. Baudelaire predicts these nuances in Les Hiboux: “Sous les ifs noirs qui les abritent…” The
if’s in procedural computer languages are followed by boolean expressions that reduce at runtime to
FALSE. Logical implication is replaced by material implication:
TRUEimplies that the
thenclause (possibly empty) is obeyed, while
elseclause (also possibly empty). Note that we lose the asymmetry of logical implication (true implies true, but false implies anything), and you are free to interchange
TRUE: they are essentially arbitrary attributes with no semantic significance. You are equally free to switch your
C is rather different. The interesting quirk with C, in the absence of a dedicated Boolean type, is that zero is Boolean
FALSE, while nonzero is
TRUE. An expression such as
(1 != 1), which most would regard as patently false, does indeed evaluate to zero;
(2 == 2)evaluates to the integer 1, which is abundantly nonzero and eminently true.
The interesting point is that
FALSEis single-valued (I exclude the metaphysics of null pointers, huge, near, and far) while
TRUEis legion. There may be a Zarathustrian strand here: the diabolical equivalence of all dark lies constrasting with a billion points of light? However, when you want a function to return
TRUEfor success and
FALSEfor failure, a perfectly natural, dare I say, intuitive ploy, you hit a snag. Success is a one-of-a-kind-blessing, failure comes in whole battalions. To have the function return an instructive error code, it is necessary to rephrase the question pessimistically: Did the function fail? Yes,
TRUE! Why did it fail? Test the nonzero return value:
Some see life itself as a huge case statement. – The computer contradictionary