Control Structure - a single logical unit of statements with one entry and one exit point, used to specify sequential control. For example:
Example
int main()
{
. . .
}
Syntax of simple if:
if (logical expression) executable statement
Syntax of if-else:
if (logical expression) executable statement_1
else executable statement_2
|
Decision Examples with Integer variables
if (x != 0) cout << "true\n"; if ( !(x == 0) ) cout << "true\n"; if (x) cout << "true\n";
Are the following two if statements functionally equivalent?
if ((n / 1000) > 0) cout << n << " has 4 or more digits.\n";
if (n / 1000) cout << n << " has 4 or more digits.\n";The answer is YES if n is positive. If n is negative, ???
if (x >= 0)
. if (x <= 10)
. . if (y == 97)
. . cout << "Yes!\n";
. . else
. . cout << "y != 97 and 0 <= x <= 10\n";
. else
. cout << "x > 10\n";
else
cout << "x < 0\n";
|
In terms of x and y, under what conditions will   YES!
  be printed?
// Display a grade-based message cin >> grade; if (grade == 'A') cout << "Excellent\n"; if (grade == 'B') cout << "Good\n"; if (grade == 'C') cout << "Average\n"; if (grade == 'D') cout << "Barely\n"; if (grade == 'F') cout << "Welcome back\n"; |
The spacing is attractive, but the code is poor for a couple of reasons. Why?
Let's rewrite this code to make it more efficient and more robust.
// Print a grade-based message
cin >> grade;
if (grade == 'A') cout << "Excellent\n";
else if (grade == 'B') cout << "Good\n";
else if (grade == 'C') cout << "Average\n";
else if (grade == 'D') cout << "Barely\n";
else if (grade == 'F') cout << "Welcome back\n";
else cout << "Input error. " << grade <<
" is an invalid grade.\n"
|
Much better! Note the style.
int code, x, flag;
cin >> code >> x;
if (code == 0) { // code is zero
cin >> x;
flag = (x >= 100);
if (flag) // code is zero AND x >= 100
cout << "3 or more digits\n";
}
else // code is not zero
cout << "code is not zero.\n";
|
The   else   clause can be a single statement or a compound statement.
Below is alternate code; study it!
int code, x, flag;
cin >> code >> x;
if (!code) { // code is zero
cin >> x;
if (x >= 100) // code is zero AND x >= 100
cout << "3 or more digits\n";
}
else // code is not zero
cout << "code is not zero.\n";
|
Run with sample data sets that structurally test the code.
For example, run three times;   1) 0, 100   2) 0, 99   3) -1, any integer
int x, y;
if (x > 5) {
if (y < 3) // x>5, y<3
cout << "Rubin \n";
else // x>5, y>=3
cout << "Cherise \n";
}
else {
if (y > 4) // x<=5, y>4
cout << "Cassidy \n";
else // x<=5, y<=4
cout << "Bertha \n";
}
|
x = 1;
  y = 2;
  z = 3;
Example
/***-----------------------------------------------------------
Function Is_odd() returns 0 if the integer is even, 1 if odd
NOTE: This code has two exit points -- not the best.
Global Constant: FALSE = 0
---------------------------------------------------------***/
int Is_odd(int x) // function header
{
if (x % 2 == 0) return FALSE; // input is an even number
else return !FALSE; // input is an odd number
}
|
In calling function:
const int FALSE = 0; if (Is_odd(n)) cout << n << " is odd.\n"; else cout << n << " is even.\n"; |
--------------------------
Now let's examine a better way to define the same function.
int Is_odd2(int x)
{
return (x % 2) != 0;
}
|
The call   Is_odd2(17)   returns   17 % 2   or 1, which is true.
The call   Is_odd2(24)   returns   24 % 2   or 0, which is false.
--------------------------
Finally, let's examine the   COOL  way to define the same function.
int Is_odd3(int x)  
{
return x % 2;
}
|
The call   Is_odd3(17)   returns   17 % 2   or 1, which is true.
The call   Is_odd3(24)   returns   24 % 2   or 0, which is false.
// Store the returned value. code = Is_odd3(value); // Test the returned value. if (Is_odd3(number)) sum += number; // Print the returned value. cout << "The returned value is " << Is_odd3(number) << endl; |
Caution: The code below doesn't use the returned value; usually not good.
Is_odd3(a); // Call Is_odd3( ), but
don't store, test, or use the returned value.
&&
and
binary operator, requires two operands
||
or
binary operator, requires two operands
!
not
unary operator, requires one operand
Given expressions p and q:
p
q
p && q
p
q
p || q
p
!p
1
1
1
1
1
0
1
0
1
0
0
0
1
0
1
0
0
0
0
Example
If p is (x > y) and q is (y >= z), then (p && q) can be written as:
(x > y) && (y >= z)
Therefore, if the expression above is true and y is 10, then
z must be <=10, and
x must be >10.
As a C statement:
    if (x > y && y >= z)   cout << "x is the largest\n";
Always ask, "What values make the condition true (non-zero)?"
For efficiency, C++ utilizes short-circuit evaluation. With an expression of the form p & q, C++ stops the evaluation if p is false. With an expression of the form p || q, C++ stops the evaluation if p is true.
Practice at home: Write a functionally equivalent piece of code for p & q without using the logical operators. Now do the same for p || q.
Example
    (a != b) || (b != c)
If the expression is true, a, b, and c are not identical. Can a equal c?
    if (a != b || b != c)
    cout << "a, b, and c are not identical.\n";
Are the two statements below functionally equivalent? Trace with various values to see.
if( a != b && b != c)   cout << "b is unique.\n";
if (!(a == b) && !(b == c))   cout << "b is unique.\n";
// is x either less than 1 or greater than 100?
if (x <= 0 || x > 100)
cout << "x not in 1 ... 100\n";
// is x between 1 and 100?
if (x > 0 && x <= 100)
cout << "Range of x is 1 ... 100\n";
|
Now let's exchange logical operators.
// Test for erroneous values of x.
if (x <= 0 && x > 100)
cout << "Not possible!!\n";
if (x > 0 || x <= 100)
cout << "Always true!\n";
|
// Is ch an uppercase alphabetic character?
if (ch >= 'A' && ch <= 'Z')
<executable statement>
// Is ch any alphabetic character?
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
<executable statement>
|
// Nested if-else statements (braces not required)
if (grade > 80) {
if (attendance > 90) {
if (lab_scores > 95) {
cout << "\n Grade is A\n"; |
// What gets printed? |
For practice, trace with x: 2 and y: 4.
For practice, trace with x: 9 and y: 9.
// What gets printed? |
========================================================
syntax: (form) switch(controlling expression) {
label set 1: statements set 1
label set 2: statements set 2
. . .
label set n: statements set n
default: statements set x
}
|
Example
cin >> grade;
switch(grade) {
case 'A': cout ... ; break;
case 'B': cout ... ; break;
case 'C': cout ... ; break;
case 'D': cout ... ; break;
case 'F': cout ... ; break;
default: cout ... ;
}
|
Example
cin >> x;
switch(x) {
case 25: x++;
case -4: x--; break;
case 62: x += 6;
default: x % 7;
}
cout << x << endl;
|
| Original value of x: | Value of x displayed: |
|   x:   25 |     25      (Be careful here!) |
|   x:   -4 |   -5 |
|   x:   62 |   67 |
|   x:   93 |       2      (default is executed) |
|   x: 0 |       7       (default is executed) |
// switch can do most of the work in a driver
cin >> key;
switch(key) {
case 'a':
cout << "Enter an integer 0 - 9: ";
cin >> quantity;
number = process(quantity);
cout << "The computed value is" << number << ".\n";
break;
case 'b':
case 'B':
<code for both key b and key B goes here.>
break;
case 'c':
<code for key c goes here.>
break;
default: error_handling_function(key);
}
|
// Use a switch statement to sum x, x-1, x-2, ..., 1
// where x is in the range 1 through 5.
sum = 0;
if (x >= 1 && x <= 5)
switch(x) {
case 5: sum = x; x--;
case 4: sum += x; x--;
case 3: sum += x; x--;
case 2: sum += x; x--;
case 1: sum += x;
}
else cout << x << " is not in the range 1-5.\n";
|
Notes on switch( ):