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 guess1.
• If guess1 is the correct guess, then tell the user “Success!” and quit.
• If guess1 is not the correct guess, then tell the user “Nope. Try another guess.” and save the second guess into a variable called guess2.
• If guess2 is the correct guess, then tell the user “Success!” and quit.
• If guess2 is not the correct guess, then tell the user “Nope. Try another guess.” and save the third guess into a variable called guess3.
• If guess3 is the correct guess, then tell the user “Success!” and quit.
• If guess3 is 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 true and false:

But these conditionals (true and 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 { and }). In the second case, the stuff in the block will never be executed.

More interesting conditionals may involve the following boolean operators (assuming p and q are bool variables and x is an int variable):

• !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/else

Besides if we can also use else to specify some operations that should be executed if the conditional is not satisfied. Example:

## Nested if’s

if commands can be inside other if (or else) blocks:

## 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 if 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.

Examples:

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.


The code:

## “switch” statements

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 switch 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 integers.

Here is an example.

The 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 switch.

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 if as 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 TRUE or FALSE. Logical implication is replaced by material implication: TRUE implies that the then clause (possibly empty) is obeyed, while FALSE triggers the else clause (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 FALSE and TRUE: they are essentially arbitrary attributes with no semantic significance. You are equally free to switch your then and else clauses.

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 FALSE is single-valued (I exclude the metaphysics of null pointers, huge, near, and far) while TRUE is 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 TRUE for success and FALSE for 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