Program with simple conditional


// File: oddeven.cpp

// -----------------

// Reads in a number and classifies it as even or odd.



#include "iostream.h"



int main()

{

    int n;



    cout << "Program to classify a number as even or odd." << endl;

    cout << "n = ? ";

    cin >> n;



    if ((n % 2) == 0) {

        cout << "That number is even." << endl;

    } else {

        cout << "That number is odd." << endl;

    }



    return 0;

}


Comparison operators, if-else syntax

Comparison operators: == != < > <= >=

Other forms of if, if-else conditionals:


if (n < 0) {

    n *= -1;

}



if (n < 0)

    n *= -1;



if ((n % 2) == 0)

    cout << "That number is even." << endl;

else

    cout << "That number is odd." << endl;

Watch out!


if ((n % 2) == 0)

    cout << "That number is even." << endl;

    cout << n << endl;

else

    cout << "That number is odd." << endl;


Cascading if-else

Cascading if-else:


if (n > 0) {

    cout << "That number is positive." << endl;

} else if (n == 0) {

    cout << "That number is zero." << endl;

} else {    // n < 0

    cout << "That number is negative." << endl;

}

Cascading conditions need not be mutually exclusive:


if (age > 65) {

    cout << "You're getting on in years." << endl;

} else if (age > 18) {

    cout << "You're old enough to vote."

} else if (age > 0) {

    cout << "You're a youngster." << endl;

} else {     // age <= 0

    cout << "You're not even born yet!" << endl;

}


Dangling else problem


// File: dangle.cpp



#include "iostream.h"



int main()

{

    int n;



    cout << "Enter a number: ";

    cin >> n;

    if (n > 2)

        if (n < 5)

            cout << "n is between 2 and 5." << endl;

    else

        cout << "n is less than or equal to 2." << endl;



    return 0;

}

What happens when it runs?


Enter a number : 3

n is between 2 and 5.



Enter a number: 7

n is less than or equal to 2.


Dangling else solution


// File: dangle2.cpp



#include "iostream.h"



int main()

{

    int n;



    cout << "Enter a number: ";

    cin >> n;

    if (n > 2) {

        if (n < 5)

            cout << "n is between 2 and 5." << endl;

    } else {

        cout << "n is less than or equal to 2." << endl;

    }



    return 0;

}

What happens when it runs?


Enter a number : 3

n is between 2 and 5.



Enter a number: 1

n is less than or equal to 2.


Using = instead of ==


// File: equal.cpp



#include "iostream.h"



int main()

{

    int n;



    n = 0;

    if (n = 0) {

        cout << "My program works!" << endl;

    } else {

        cout << "What's wrong??" << endl;

    }



    return 0;

}

What happens when it runs?


What's wrong??


Boolean value usage

There's no built-in boolean type (my mistake)! Some compilers' libraries may provide it.

A condition using comparison or logical operators evaluates to 1 if true, 0 if false.

Convenient constants you can define


const int true = 1;

const int false = 0;



const int TRUE = 1;

const int FALSE = 0;

Allows you to write something like:


int isPositive, num;

isPositive = (num > 0);



if (isPositive == true) { ...

Or simply:


if (isPositive) { ...


Logical operators

Not     !


    X            !X

    true         false

    false        true

And     &&


    X            Y            X && Y

    true         true         true

    true         false        false

    false        true         false

    false        false        false

Or     ||


    X            Y            X || Y

    true         true         true

    true         false        true

    false        true         true

    false        false        false


Precedence, DeMorgan's Laws

Precedence:


    ++ -- !

    * / %

    + -

    < > <= >=

    == !=

    &&

    ||



    !p || q && r < 5 --> (!p) || (q && (r < 5))

DeMorgan's Laws:

!(p && q) is equivalent to !p || !q
!(p || q) is equivalent to !p && !q

"x is neither 2 nor 3"

(x != 2) && (x != 3)
!(x == 2 || x == 3)

"x is between 1 and 10"

1 <= x && x <= 10

Short circuit evaluation

expr2 is evaluated only if...
expr1 && expr2 expr1 is true
expr1 || expr2 expr1 is false

Guard condition:

if ((x != 0) && (y / x == 3)) ...

What's the output?


    int flag;

    int a = 3, n = 2;



    flag = (a < 5) || (++n < 5);

    cout << "n = " << n << endl;

    flag = (a > 5) || (++n < 5);

    cout << "n = " << n << endl;


Conditional style, isLeapYear exercise

Forms to avoid:


    int done;

    int itemsRemaining;



    if (itemsRemaining == 0) {            done = (itemsRemaining == 0);

        done = true;

    } else {

        done = false;

    }



    if (done == true) {                   if (done) {

        ...

    }



    if (done == false) {                  if (!done) {

        ...

    }

Write a condition which is true if a year is a leap year...

A leap year occurs if the year is evenly divisible by 4, but not if it ends in 00, unless it is evenly divisible by 400. 2000 is a leap year; 1900, 1995 are not.


    int year;

    int isLeapYear;



    cout << "What year? ";

    cin >> year;

    isLeapYear = 


Lengthy cascading if-else

Task: convert playing card rank (1-13) into appropriate printed output.


int main()

{

    int n;



    cout << "What is the rank of the card (1-13) ? ";

    cin >> n;



    if (n == 1) {

        cout << "Ace" << endl;

    } else if (n == 11) {

        cout << "Jack" << endl;

    } else if (n == 12) {

        cout << "Queen" << endl;

    } else if (n == 13) {

        cout << "King" << endl;

    } else {

        cout << n << endl;

    }

    return 0;

}


Using switch

Same thing, using switch:


    switch (n) {

        case 1:     cout << "Ace" << endl;

                    break;

        case 11:    cout << "Jack" << endl;

                    break;

        case 12:    cout << "Queen" << endl;

                    break;

        case 13:    cout << "King" << endl;

                    break;

        default:    cout << n << endl;

                    break;

    }

Grouping cases in a switch:


    switch (n) {

        case 11:

        case 12:

        case 13:

                cout << "Face card." << endl;

                    break;

        default:

                    cout << "Not a face card." << endl;

                    break;

    }


Forgetting break

What happens if you forget break:


    switch (n) {

        case 11:

        case 12:

        case 13:

                cout << "Face card." << endl;

        default:

                cout << "Not a face card." << endl;

                break;

    }

Sample run:


What is the rank of the card (1-13) ? 12

Face card.

Not a face card.


Definite iteration with for loop

Definite iteration: the repeat-n-times idiom


for (i = 0; i < n; i++) {

    statements to be repeated

}



for (i = 0; i < 10; i++) {

    cout << "I will not chew gum in class." << endl;

}

Using the loop control variable in the body of the loop:


for (i = 0; i < 5; i++) {

    cout << i << ") I will not chew gum in class." << endl;

}

Output:


0) I will not chew gum in class.

1) I will not chew gum in class.

2) I will not chew gum in class.

3) I will not chew gum in class.

4) I will not chew gum in class.


Starting for loop from 1

Same thing, but starting from 1:


for (i = 1; i <= 5; i++) {

    cout << i << ") I will not chew gum in class." << endl;

}

Output:


1) I will not chew gum in class.

2) I will not chew gum in class.

3) I will not chew gum in class.

4) I will not chew gum in class.

5) I will not chew gum in class.


Program to add ten numbers


// File: add10.cpp

// ---------------

// This program adds ten inputted numbers and prints their total.



#include "iostream.h"



int main()

{

    int i, value, total;



    cout << "This program adds a list of ten numbers." << endl;



    total = 0;

    for (i = 0; i < 10; i++) {

        cout << " ? ";

        cin >> value;

        total += value;

    }



    cout << "The total is " << total << "." << endl;



    return 0;

}

Sample run:


This program adds a list of ten numbers.

 ? 13

 ? 21

 ? 17

 ? 19

 ? 21

 ? 47

 ? 33

 ? 10

 ? 60

 ? 35

The total is 276.


Syntax of for loop

General form of for loop:


for (init; test; step)

    statement



for (init; test; step) {

    statements

}





for (i = 0; i < n; i++) ...

for (i = 1; i <= n; i++) ...

for (i = -7; i < 0; i += 3) ...

for ( ; i > n; i--) ...

for (i = 0; i < n; ) ...

for (;;) ...

Caution:


for (i = 0; i < 10; i++);

    cout << "Hello!" << endl;


Floating-point data comparison caution

Floating-point data comparisons: be careful!


double x;

for (x = 1.0; x <= 2.0; x += 0.1) {

    cout << x << endl;

}

Sample output:


1

1.1

1.2

1.3

1.4

1.5

1.6

1.7

1.8

1.9

Second try: will print from 1 to 2, inclusive, by tenths


int i;

for (i = 10; i <= 20; i++) {

    cout << (i * 0.1) << endl;

}


Nested for loops


// Generate a multiplication table.



#include "iostream.h"



int main()

{

    const int LowerLimit = 1;

    const int UpperLimit = 10;



    int i, j;



    for (i = LowerLimit; i <= UpperLimit; i++) {

        for (j = LowerLimit; j <= UpperLimit; j++) {

            cout.width(4);

            cout << i * j;

        }

        cout << endl;

    }



    return 0;

}

Sample run:


   1   2   3   4   5   6   7   8   9  10

   2   4   6   8  10  12  14  16  18  20

   3   6   9  12  15  18  21  24  27  30

   4   8  12  16  20  24  28  32  36  40

   5  10  15  20  25  30  35  40  45  50

   6  12  18  24  30  36  42  48  54  60

   7  14  21  28  35  42  49  56  63  70

   8  16  24  32  40  48  56  64  72  80

   9  18  27  36  45  54  63  72  81  90

  10  20  30  40  50  60  70  80  90 100


Lab: Print even squares

Task: Write a program that prompts the user to enter a number n, then prints all even squares between 1 and n. For example, if the user enters 100, the program should print the following numbers: 4, 16, 36, 64, 100. Hint: use a for loop with a more complex conditional test than I've used in my examples.

One way to approach the problem: first write code to print the squares of all the numbers from 1 and n. Next modify your loop to stop when the squares get greater than n. Finally, add code so that only the even squares get printed (there are a couple of ways to do this).


List headed by size

Task: sum a list of numbers, with the number of numbers not known in advance.

List-headed-by-size


int main()

{

    int i, n, value, total = 0;



    cout << "How many numbers to be entered? ";

    cin >> n;

    for (i = 0; i < n; i++) {

        cout << " ? ";

        cin >> value;

        total += value;

    }

    cout << "The total is " << total << endl;

    return 0;

}

Sample run:


How many numbers to be entered?

 ? 5

 ? 3

 ? 7

 ? 503

 ? -10

 ? 29

The total is 537


Loop until sentinel: while with break

Loop-until-sentinel


int main()

{

    int value, total = 0;



    cout << "This program adds a list of numbers." << endl;

    cout << "Signal end of list with a 0." << endl;

    while (true) {

        cout << " ? ";

        cin >> value;

        if (value == 0) break;

        total += value;

   }

    cout << "The total is " << total << endl;

    return 0;

}

Sample run:


This program adds a list of numbers.

Signal end of list with a 0.

 ? 8

 ? 33

 ? 115

 ? -24

 ? 2000

 ? 434

 ? 0

The total is 2566


Loop until sentinel: while without break

Note duplication of value input code.


int main()

{

    int value, total = 0;



    cout << "This program adds a list of numbers." << endl;

    cout << "Signal end of list with a 0." << endl;

    cout << " ? ";

    cin >> value;

    while (value != 0) {

        total += value;

        cout << " ? ";

        cin >> value;

    }

    cout << "The total is " << total << endl;



    return 0;

}


Syntax of while and do-while loops

Indefinite iteration: while and do-while loop


while (condition) {

    statements

}

Semantics: evaluate condition; if condition is true, execute statements, and repeat, otherwise terminate execution of loop


do {

    statements

} while (condition)

Semantics: execute statements, then evaluate condition; if condition is true, repeat, otherwise terminate execution of loop


Loop until sentinel: do-while, Lab: Product of a list of numbers

Loop-until-sentinel using do-while


int main()

{

    int value, total = 0;



    cout << "This program adds a list of numbers." << endl;

    cout << "Signal end of list with a 0." << endl;

    do {

        cout << " ? ";

        cin >> value;

        total += value;

    } while (value != 0);

    cout << "The total is " << total << endl;



    return 0;

}

Does it solve the duplicated code problem? Notice that the sentinel value actually gets added to the total. Since the sentinel value is zero and we're summing, the result displayed is correct. Can this be guaranteed in general?

Lab:

Write a loop with sentinel to compute the product of a list of non-zero numbers (positive and negative). Try using each of the loop-with-sentinel schemes (while with break, while without break, do-while). Which method seems to work best?


Program to determine minimum and average


// File: min-avg.cpp

// This program finds the minimum and average values of a list of numbers

// entered by the user.  The end of the list is indicated by entering -1.



#include "iostream.h"



int main()

{

    const int SENTINEL = -1;



    int value, total = 0, minimum, itemCount = 0;

    double average;



    cout << "Signal end of list with " << SENTINEL << "." << endl;



    cout << " ? ";

    cin >> value;

    minimum = value;



    while (value != SENTINEL) {

        itemCount++;

        total += value;

        if (value < minimum) minimum = value;

        cout << " ? ";

        cin >> value;

    }



    if (itemCount > 0) {

        cout << "Smallest value: " << minimum << endl;

        average = double(total) / itemCount;

        cout << "Average value: " << average << endl;

    } else {

        cout << "No items were entered." << endl;

    }



    return 0;

}


Sample run


Signal end of list with -1.

 ? 54

 ? 34

 ? 15

 ? 0

 ? 49

 ? 51

 ? 42

 ? 28

 ? -1

Smallest value: 0

Average value: 34.125


Top-down design of program to sum digits in a number

While loop application other than loop-with-sentinel!

Task: write a program which adds up the individual digits in a positive integer. Expected behavior:


This program sums the digits in an integer.

Enter a positive integer: 16385

The sum of the digits is 23.

General program structure (top down design):


    introductory message

    prompt for and get input

    initialize sum

    for each digit in number, add the digit to the sum

    display the answer

Partial solution:


int main()

{

    int num, digitSum;

    cout << "This program sums the digits in an integer." << endl;

    cout << "Enter a positive integer: ";

    cin >> num;

    digitSum = 0;

    for each digit in number, add the digit to the sum

    cout << "The sum of the digits is " << digitSum << "." << endl;



    return 0;

}

Questions:

What kind of loop, for (definite iteration) or while (indefinite iteration)? How to isolate one digit from a number? Which digit is easiest to isolate? Hint: rightmost or leftmost?


Getting one's digit, Exercise: Condition of the loop

Body of loop:


    Modulo 10 to get rightmost digit

    Add digit to digit sum

    Integer division of number by 10 to discard rightmost digit,

        "shift" remaining digits to the right

So now we have:


    while (condition) {

        digitSum += (num % 10);

        num /= 10;

    }

What should the condition be?


Full solution, Infinite loops

The full solution:


int main()

{

    int num, digitSum;

    cout << "This program sums the digits in an integer." << endl;

    cout << "Enter a positive integer: ";

    cin >> num;

    digitSum = 0;



    while (num > 0) {

        digitSum += (num % 10);

        num /= 10;

    }



    cout << "The sum of the digits is " << digitSum << "." << endl;



    return 0;

}

Infinite loops (logic error):

It's your responsibility to insure the loop will eventually be exited.


    while (num >= 0) {

        digitSum += (num % 10);

        num /= 10;

    }

Use Ctrl-Alt-SysRq to interrupt an infinite loop in Borland C++.


Lab: Greatest Common Divisor

Write a program that asks the user to enter two integers, then calculates and displays their greatest common divisor (GCD).


Enter two integers: 12 28

Greatest common divisor: 4

To compute the GCD, use Euclid's algorithm: Let m and n be variables containing the two numbers. Divide m by n. Save the divisor (n) in m, and save the remainder in n. If n is 0, then stop; m contains the GCD. Otherwise, repeat the process, starting with the division of m by n.