Welcome to Lesson 11!

Learning Objectives

By the end of today's class, you should know...
  • What are the 3 logical operators?
  • How do you test multiple conditions using logical operators?
  • How do && and || operate when:
    • both test conditions evaluate to true?
    • both test conditions evaluate to false?
    • one test condition evaluates to true and one to false?
  • What are some of the mistakes you could make when you write your conditional statements involving logical operators?

Announcements

  • Return Midterms in the last 5 minutes of class - excellent results!
    • As: 33
    • Bs: 5
    • Cs: 3
    • Ds: 2
    • Fs: 1
  • De Anza Women in CS club meeting tomorrow at 12:30 in ATC 202!
  • Next quiz on Thursday
    • Numbers, Operators and Precision
    • Logical Operators
    • While loops (simple)


Review Activity

Review of Numbers, Operators and Precision:

  • With a partner: Write three equivalent statements to the one below, using the shortcuts described last class:
x = x + 1;
  • With a partner: Write one statement to print the following value to the console to 5 decimal places:
        double PI = 3.1415927;
  • With a partner: Declare a constant variable called FEET_PER_YARD and assign it the value of 3.

Logical Operators

  • In certain situations, we may wish to use more than one test condition inside of an if statement.
  • To do so, we will need to chain the test conditions together using logical operators (either && or ||)
  • For example, recall our guessing game program:
        cout << "I'm thinking of a number between 1 and 10.\n";
    cout << "Can you guess it?\n\n";
    cout << "Enter your guess: ";
        
    cin >> guess;
        
    if (guess < 1 || guess > 10) { //if guess is < 1 OR guess > 10
        cout << "Invalid entry!";
    } else if (guess < 7) {
        cout << "Your guess is too low";
    } else if (guess > 7) {
        cout << "Your guess is too high";
    } else {
        cout << "*** Correct! ***";
    }

Review of Boolean Variables

  • Sometime we need to evaluate a logical condition in one part of a program and use it elsewhere
  • To store a condition that can only be true or false, we use a Boolean variable
  • Boolean variables are named after George Boole (1815-1864), a pioneer in the study of logic
  • We specify a Boolean variable using the bool type, which can hold just one of two values: true or false
    bool isCool = true;
    bool lies = false; 


Test Conditions and Boolean Values

  • Remember that test conditions always evaluate to true or false
    if (num > 0)
    
  • Thus we can use a boolean variable as a test condition
    bool isPositive = (num >= 0);
    if (isPositive)
    
  • Note that we do not need to add a relational expression to a boolean variable, like:
    if (isPositive == true) // avoid!
  • Since the boolean variable already evaluates to true or false, adding the == true is redundant
  • Likewise, we do not need to use:
    if (isPositive != false) // avoid!
  • If we want to reverse the test condition, we can use the not (!) operator
    if (!isPositive)
  • We can see the use of a boolean variable in the following example


Example Application Using a Boolean Variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


#include <iostream>
using namespace std;
int main() {
    double num;
   cout << "Enter a number: "; cin >> num; bool isPositive = (num >= 0); cout << boolalpha << "The test evaluated to: " << isPositive << endl; if (isPositive) { cout << "The number was 0 or positive\n"; } else { cout << "The number was negative\n"; } }

Introducing &&, || and !

Logical operators and search engines video


Combining Test Conditions with Logical Operators

  • logical operator, or boolean operator, is an operator that treats operands as boolean values (true or false)
  • C++ has several logical operators, but we only need to use three to create any possible test condition
  • These three operators are andor and not, which are discussed below
  • These logical operators are traditionally written as && (and), || (or) and ! (not)

Truth Tables for AND, OR and NOT

&& (AND) Operator Truth Table
expr1
expr2
expr1 && expr2
ExampleResult
truetruetrue5 < 10 && 5 > 2true
truefalsefalse5 < 10 && 5 < 2false
falsetruefalse5 > 10 && 5 > 2false
falsefalsefalse5 > 10 && 5 < 2false
|| (OR) Operator Truth Table
expr1
expr2
expr1 || expr2
ExampleResult
truetruetrue5 < 10 || 5 > 2true
truefalsetrue5 < 10 || 5 < 2true
falsetruetrue5 > 10 || 5 > 2true
falsefalsefalse5 > 10 || 5 < 2false
not (!) Operator Truth Table
If expr is...Then ! expr is...ExampleResult
truefalse!truefalse
falsetrue!(5 < 2)true


Testing Multiple Conditions Using Logical Operators

  • Sometimes we need to test for multiple conditions using a single if statement
  • In this case, we will need to chain together the two conditions using a logical operator, either && or ||
  • Note that one either side of the logical operator there must be a stand alone test condition

if (age >= 18 && age <= 25) //Correct!!!

if (age >= 18 && <= 25) //No! Incorrect!!

  • For example, we want to test if an age is between 18 and 65
  • We need to test that both parts of are true: that the age is >= 18 AND that the age is <= 65

int age = 0;
cout << "Enter your age: ";
cin >> age;
if (age >= 18 && age <= 65)
{
    cout << "Adult!\n";
} else {
    cout << "Child, Teen or Older Adult!\n";
}


  • Another way to use logical operators to test the age is:
    int age = 0;
    cout << "Enter your age: ";
    cin >> age;
    if (age < 18 || age > 65)
    {
        cout << "Child, Teen or Older Adult!\n";
    } else {
        cout << "Adult!\n";
    }
    
  • Many people confuse && and || conditions, especially when learning about logical operators
  • A value lies between 18 and 65 if the value is at least 18 and at most 65
  • A value is outside that range if it is less than 18 or greater than 65
  • There is no golden rule; we have to think carefully and test our conditions

Parenthesis

  • Remember that a Boolean expression in an if statement must be enclosed in parenthesis
  • Thus, an if statement with && might look like:
    if ((guess != GUESS1) && (guess != GUESS2))
  • However, relational operators have a higher precedence than logical operators
  • Thus, we can remove the inner parenthesis without affecting the meaning:
    if (guess != GUESS1 && guess != GUESS2)
  • However, if using parenthesis is easier to understand then use the extra parenthesis


Activity 11.1: What's Your Generation? (10 pts)

  • There are 6 generations living in America, side-by-side, today.
  • Your program will determine to which generation your user belongs.
  • Find a partner for pair programming and open up a new file and name it generation.cpp.
  • To do so, you will need to take as input the year of his or her birth.
  • Then, you will need a series of test conditions (think if - else if - else) to determine the generation of your user.
  • You will also need to use logical operators (&&, ||, !).
  • Below is a chart with the range of birth years for each generation.
  • Note the double quotes around each generation's name. For full credit, you must include the " when you output the generation.
Years of Birth                    Generation
1900-1927                           "The Greatest Generation"
1928-1945                           "The Silents"
1946-1964                           "The Baby Boomers"
1965-1979                           "Generation X"
1980-1999                           "The Millennial Generation"
2000-2018                           "Generation Z"

  • Your goal is to prompt the user for his or her date of birth and then print out a message about which generation he or she belongs to.
  • To start, print the following message to the user:

    What's your generation?
  • Then, you will need a variable to store the user's year of birth:
int year_of_birth;
  • Next, prompt your user to enter his or her date of birth with a statement like the following:
Please enter the year of your birth: _
  • Subsequently, you will need 6 if and if else statements like the following:
if ( year_of_birth >= 1900 && year_of_birth < 1928)
{
    cout << "You belong to the \"Greatest Generation\"" << endl;
}
else if ( year_of_birth >= 1928 && year_of_birth < 1946)
{
    cout << "You belong to the \"The Silents\"" << endl;
}
//rest of your else ifs and your else clause go here
  • Important: Why are we using && here and not ||?
  • Finally, you will need to do some error checking of the user input.
  • If the user inputs a date that is either too high or too low, your program must print out the following message:
Invalid entry. Please enter a birth year in the range 1900 - 2018.
  • The above should go in your else clause
  • Make sure your output is identical to the sample output below before you submit.
  • When you are finished, upload to Canvas

What's your generation?
Please enter the year of your birth: 1926
You belong to the "Greatest Generation".

Alternately,

What's your generation?
Please enter the year of your birth: 2025
Invalid entry! Please enter a birth year in the range 1900 - 2018.

More Information on Logical Operators


Conditional Pitfalls

  • Unfortunately, you can write many things in C++ that should be incorrect but end up working for some obscure reason
  • This means that you can code something that should create an error message but does not
  • Thus, a program may compile and run with no error messages but still be wrong
  • Since you may not realize that it is wrong, it can be hard to find and correct these types of errors

Strings of Inequalities

  • One common mistake is to use = when you meant to use ==
  • For example, look at the test condition in the following code:
    if (guess = 7) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    
  • Notice that the condition is really an assignment statement and not a test
  • You would think that it would fail to compile -- but it does not
  • However, it will not work as you might expect
  • A way to prevent this type of problem is to reverse the order of your test condition:
    if (7 = guess) {
  • Now the compiler will give you an error message and your code will not compile:
    guess.cpp: In function `int main()":
    guess.cpp:10: error: non-lvalue in assignment
    
  • However, if you correctly use == then your code will compile
    if (7 == guess) {

Strings of Inequalities

  • Do NOT use a string of inequalities like the following:
    int a = 5, b = 1, c = 10;
    if (a < b < c) {
        cout << "b is between a and c\n";
    } else {
        cout << "b is NOT between a and c\n";
    }
    
  • Your code may compile and run but give incorrect results
  • The test condition is evaluated by the computer from left to right
  • The first condition is a < b which evaluates to 0 (false)
  • The second condition is then 0 < c which evaluates to 1 (true)
  • Since the whole test condition evaluates to true you get an incorrect result
  • Instead, the correct way is to use && as follows:
    int a = 5, b = 1, c = 10;
    if (a < b && b < c) {
        cout << "b is between a and c\n";
    } else {
        cout << "b is NOT between a and c\n";
    }
    

Strings of Logical Operators

  • Logical expressions often read like "normal" English.
  • However, C++ requires more exactness than English
  • For example, the following code will compile and run but give wrong results:
    int guess;
    cout << "Enter a guess: ";
    cin >> guess;
    if (guess == 7 || 8) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    
  • The test condition is evaluated by the computer from left to right
  • The left hand side is (guess == 7) which can evaluate to either true or false
  • The right hand side is 8, which is interpreted as true by C++
  • Since (something or true) is always true, then the test condition always evaluates to true
  • Instead, the correct way is to use || as follows:
  • int guess;
    cout << "Enter a guess: ";
    cin >> guess;
    if (guess == 7 || guess == 8) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
  • We will work more with test conditions and logical operators as we write programs containing loops.


Wrap Up


With a partner, answer the following questions:
  • Label the different parts of the following while loop as: update statement, initialization or test condition.

int count = 1;

while (count <= 10) {

    cout << count << endl;

    count++;

}

  • Correct the loop below (hint it is missing something!). What will happen if you run the code BEFORE making the correction?

string repeat = "y";

while (repeat == "y") {

    cout << "Playing an exciting game!\n\n";

    cout << "Want to play again? (y/n): ";

}

  • Answer the questions from today's learning objectives.


Upcoming Assignments

  • Assignment 11 due Thursday at 9:20am
  • Lab 6 due Friday
  • Quiz next class!

~See You Thursday!~