Selection

C/C++ has two selection constructs, the if and the switch statements.
  1. Relational operators are used to describe the relationship between operands. The relational operators are :
    1. > greater than
    2. >= greater than or equal.
    3. < less than
    4. <= less than or equal
    5. == equal ( do not confuse this with =).
    6. != not equal

      If the relationship is true the expression returns a 1. If it is false the expression returns a 0.

  2. Logical operators are used to build complex expression. The 3 logical operators are :
    1. && and
      If either operand is zero, and returns a 0. If both operands are non zero and returns a 1.
      ABA && B
      TrueTrueTrue
      TrueFalseFalse
      FalseTrueFalse
      FalseFalseFalse
    2. || or
      If both operands are zero return a zero (0), If either operand is non zero return a 1.
      ABA || B
      TrueTrueTrue
      TrueFalseTrue
      FalseTrueTrue
      FalseFalseFalse
    3. ! not
      Returns 0 if given non zero, returns 1 if given 0.
      A ! A
      TrueFalse
      FalseTrue

    4. Precedence
      The order of precedence is ! && ||
      Fill in the following Truth table
      ABCA || B && C
      TrueTrueTrue     
      TrueTrueFalse     
      TrueFalseTrue     
      TrueFalseFalse     
      FalseTrueTrue     
      FalseTrueFalse     
      FalseFalseTrue     
      FalseFalseFalse     

      AB! (A && B)
      TrueTrue     
      TrueFalse     
      FalseTrue     
      FalseFalse     

  3. Logic short circuit
    Why does this code
    #include <iostream>
    using namespace std;
     
    int main()
    {
       int a=1,b=2;
      
       a < b && cout << "Test One   " << endl;
       a > b && cout << "Test Two   " << endl;
       a < b || cout << "Test Three " << endl;
       a > b || cout << "Test Four  " << endl;
      
       system("pause");
       return 0;
    }
    
    
    Yield
    Test One
    Test Four
    Press any key to continue . . .
    

  4. The conditional expression has the form

    a ? b : c

    If a evaluates to nonzero then the b is the value of the expression, if a evaluates to zero then c is the value of the expression. For example:
     int a=5,b;
     
         b = a > 5 ? 4 : 3;
    

  5. if
    The basic format of the if statement is :
        if (expression) statement;
    
    If the expression evaluates to nonzero the statement is executed. If you wish multiple statements executed, then they must be enclosed in { }.
    1. Simple if.
       if (x == 3) cout << y << endl;
      
      
    2. Multiple statement if.
         if(x > 0) {
           x += y;
           y <<=3;
           z=0;
         }
      
    3. Complex logic if.
      #include <iostream>
      using namespace std;
      
      void year_check(int);
      bool is_leap(int);
      
      int main()
      {
         year_check(1753);
         year_check(1900);
         year_check(2000);
         year_check(2005);
         year_check(2008);
      
         system("pause");
         return 0;
      }
      
      void year_check(int year)
      {
         cout << year
              << (is_leap(year) ? " is " : " is not ")
              << " a leap year " &t;&t; endl;
      }
      
      bool is_leap(int year)
      {
         return (  year %4 == 0 &&
                  ( year % 100   ||
                  !(year % 400)
                  )
                );
      }
      
      1753 is not  a leap year
      1900 is not  a leap year
      2000 is  a leap year
      2005 is not  a leap year
      2008 is  a leap year
      Press any key to continue . . .
      
      

  6. else
    The else statement is used to select a statement if the expression in the if evaluates to zero.
      if(x==3) cout << y << endl;
      else x+=y;
    
    1. Cascading if.. else
      The syntax of the else statement was designed to cascading if..else like:
      if (mon==1) days=31;
      else if (mon==2) days=28;
      else if (mon==3) days=31;
      else if (mon==4) days=30;
      else if (mon==5) days=31;
      else if (mon==6) days=30;
      else if (mon==7) days=31;
      else if (mon==8) days=31;
      else if (mon==9) days=30;
      else if (mon==10) days=31;
      else if (mon==11) days=30;
      else if (mon==12) days=31;
      

      The meaning is clearer if we indent the logic so that the else statements line up with the corresponding if statement like:
      if (mon==1) days=31;
      else if (mon==2) days=28;
           else if (mon==3) days=31;
                else if (mon==4) days=30;
                     else if (mon==5) days=31;
                          else if (mon==6) days=30;
                               else if (mon==7) days=31;
                                    else if (mon==8) days=31;
                                         else if (mon==9) days=30;
                                              else if (mon==10) days=31;
                                                   else if (mon==11) days=30;
                                                        else if (mon==12) days=31;
      

    2. Dangling else
      What value is assigned to z in the following code?
       int x=1,y=1,z,a;
       
       if(x==0)
         if (y==0) z=1;
       else {
         z=2;
         a=3;
       }
      
      
      z keeps a value of zero since it was not initialized. Else statements line up with the closest unattached if statement. This problem is know as the dangling else. What the code sees is:
       int x=1,y=1,z,a;
       
       if(x==0)
         if (y==0) z=1;
            else {
                z=2;
                a=3;
            }
      
      To get the prior meaning the code would need to be written as:
       int x=1,y=1,z,a;
       
       if(x==0) {
         if (y==0) z=1;
       }
       else {
         z=2;
         a=3;
       }
      
      or as
       int x=1,y=1,z,a;
       
       if(x==0)
         if (y==0) z=1;
         else ;
       else {
         z=2;
         a=3;
       }
      

  7. switch
    The syntax of the switch statement is:
      switch (expression)
      {
        case constant1 : statement1;
        case constant2 : statement2;
         .
         .
        case constant :  statement;
      }
    
    Where constant1, constant2.. constantn are possible values of expression. They must be integer type (char, short, int, long). If the expression matches the constant control is transferred to that statement that follows the constant.
    1. Rewriting the cascading if as a switch we get:
          switch (mon) {
              case   1 : days=31; break;
              case   2 : days=28; break;
              case   3 : days=31; break;
              case   4 : days=30; break;
              case   5 : days=31; break;
              case   6 : days=30; break;
              case   7 : days=31; break;
              case   8 : days=31; break;
              case   9 : days=30; break;
              case  10 : days=31; break;
              case  11 : days=30; break;
              case  12 : days=31;
         }
      
      Since the switch is implemented as a computed goto instead of the Pascal case statement, the break statement is necessary to bypass code.

    2. The constants need not be in any order and you may group statements like:
         switch (mon) {
          case 2 : days=28; break;
          case 4 :
          case 6 :
          case 9 :
          case 11 : days=30; break;
          case 1 :
          case 3 :
          case 5 :
          case 7 :
          case 8 :
          case 10 :
          case 12 : days=31;
        }
      

    3. If the expression does not match any of the constant values it will fall thru without executing any code. You can specify a default case that will be selected if the expression does not match any specified cases.
         switch (mon) {
          case 2 : if(year%4) days=28;
                   else days=29;
                   break;
          case 4 :
          case 6 :
          case 9 :
          case 11 : days=30; break;
          default : days=31;
        }
      

  8. Examples.
    1. Given 3 integer line lengths. Determine if you can construct a triangle from these lengths. If you can construct a triangle, is it equilateral, isosceles or scalene? Is it a right triangle?
      #include <iostream>
      
      using namespace std;
      
      void triangle        (int, int, int);
      bool is_valid        (int, int, int);
      bool is_triangle     (int, int, int);
      bool is_equilateral  (int, int, int);
      bool is_isosceles    (int, int, int);
      bool is_right        (int, int, int);
      int  max             (int, int);
      
      int main()
      {
         triangle(0,1,2);
         triangle(1,2,3);
         triangle(3,3,3);
         triangle(4,4,6);
         triangle(2,3,4);
         triangle(3,4,5);
      
         system("pause");
         return 0;
      }
      
      void triangle(int side1, int side2, int side3)
      {
         cout << "For sides "
              << side1 << ", "
              << side2 << ", "
              << side3 << " ";
      	 
         if(is_valid(side1,side2,side3))
           if(is_triangle(side1, side2, side3))
             if(is_equilateral(side1, side2, side3))
               cout << "Equilateral Triangle " << endl;
             else if(is_isosceles(side1, side2, side3))
               cout << "Isosceles Triangle" << endl;
             else {
               cout << "Scalene Triangle " << endl;
               if(is_right(side1, side2, side3))
                 cout << "Also a right triangle" << endl;
             }
           else cout << "not a triangle" << endl;
         else cout << "invalid input data " << endl;
      }
      
      bool is_valid(int a, int b, int c)
      {
      //  true if input valid
         bool result = a > 0 && b > 0 && c > 0;
         return result;
      }
      
      bool is_triangle(int a, int b, int c)
      {
      // true if valid triangle line lengths
         bool result = a + b > c && a + c > b && b + c > a;
         return result;
      }
      
      bool is_equilateral(int a, int b, int c)
      {
      // true if equilateral triangle
         bool result = a == b && b == c;
         return result;
      }
      
      bool is_isosceles(int a, int b, int c)
      {
      // true is isosceles triangle
         bool result = a == b || a == c || b == c;
         result = result && !(is_equilateral(a,b,c));
         return result;
      }
      
      bool is_right(int a, int b, int c)
      {
      // true if right triangle
         int h; // hypotenuse
         bool result;
         h = max(a, max(b,c));
         result = h * h == a * a + b * b + c * c - h * h;
         return result;
      }
      
      int max(int x, int y)
      {
      // return the max of x and y
         return x > y ? x : y;
      }
      
      For sides 0, 1, 2 invalid input data
      For sides 1, 2, 3 not a triangle
      For sides 3, 3, 3 Equilateral Triangle
      For sides 4, 4, 6 Isosceles Triangle
      For sides 2, 3, 4 Scalene Triangle
      For sides 3, 4, 5 Scalene Triangle
      Also a right triangle
      Press any key to continue . . .
      
      

    2. Zeller's Congruence.
      To calculate the day of the week for a given date, Zeller's congruence can be applied. A date is expressed as follows:
      • "m" month number, with January and February taken as months 11 and 12 of the preceding year. Then March is 1, April is 2.. December is 10.
      • "k" day of the month
      • "C" The century
      • "D" The year in the century.
      • "f" The day of the week where 0 = Sunday, 1 = Monday ... 6 = Saturday
      The congruence is

      f={[2.6m-0.2]+k+D+[D/4]+[C/4]-2C} % 7

      [] denotes the greatest integer in.
      The formula relies on the mathematician's definition of modulo division, which means that -2 mod 7 is equal to positive 5. Unfortunately, the way most computer languages implement the remainder function, -2 mod 7 returns a result of -2.
      #include <iostream>
      using namespace std;
      
      void zeller(int, int, int);
      
      int main()
      {
         zeller( 9,11, 2001);    // 9-11
         zeller(12,25, 2010);    // Christmas
         zeller( 7, 4, 1776);    // 1st 4th
         zeller(12, 7, 1941);    // Pearl harbor
         zeller( 1, 1, 2000);    // Y2K
         zeller( 6, 6, 1944);    // D-Day
         zeller( 7,20, 1969);    // Apollo 11 landing
      	 
         system("pause");
         return 0;
      }
      
      void zeller(int month, int day, int year)
      {
         int century ,dow;
      
         cout << month << "/"
              << day   << "/"
              << year  << " occurs on ";
      		  
         month -= 2;                         // Subtract two from month
         if (month < = 0) {                 // Prior year?
           month += 12;                     // adjust month
           year--;                          // adjust year
         }
         century = year / 100;             // Extract century
         year %= 100;                      // extract year in century
      
         dow = ((int)(2.6 * month - 0.2) +   // Zeller congruence
                 day + year + year / 4   +
      	   century / 4 - 2 * century
               ) % 7;
      
         dow += dow < 0 ? 7 : 0;           // fix for negative number.
      
         switch(dow) {
            case 0 : cout << "Sunday"    << endl; break;
            case 1 : cout << "Monday"    << endl; break;
            case 2 : cout << "Tuesday"   << endl; break;
            case 3 : cout << "Wednesday" << endl; break;
            case 4 : cout << "Thursday"  << endl; break;
            case 5 : cout << "Friday"    << endl; break;
            case 6 : cout << "Saturday"  << endl;
         }
      }
      
      
      9/11/2001 occurs on Tuesday
      12/25/2010 occurs on Saturday
      7/4/1776 occurs on Thursday
      12/7/1941 occurs on Sunday
      1/1/2000 occurs on Saturday
      6/6/1944 occurs on Tuesday
      7/20/1969 occurs on Sunday
      Press any key to continue . . .
      
      
    :