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.h>
      main()
      {
       int year=1753;
       
       while( year<2400) {
          if(year%4==0 && (year%100 || !(year%400)))
            cout << year << " is a leap year" << endl;
          year++;
       }
      }
      

  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. Write a program that will read in 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 main()
      { 
       int a,b,c,h;
       
       cout << "enter three numbers. ";
       cin >> a >> b >>c;
       cout << "the numbers are" << a << " " << b << " " << c << endl;
       
       if (a>0 && b>0 && c>0) {                     //  Test for valid input 
          if (a+b>c && a+c>b && b+c>a) {            //  Test for triangle 
             if (a==b && b==c)  {                    //  Equilateral?
                cout << " Equilateral triangle << endl;
              }
              else if (a==b || b==c || a==c) {       //  Isosceles?
                      cout << " Isosceles triangle" << endl;
                   }
                   else {                            // Scalene
                      cout << " Scalene triangle" << endl;
                      h = (b>a?(b>c?b:c):(a>c?a:c));  // Find largest side
                      if (h*h == a*a+b*b+c*c-h*h)                // Right ?
                         cout << "Also a right triangle" << endl;
                   }
          }
          else cout << " Not a triangle" << endl;
       }                                           
       else  cout << " Invalid numbers" << endl;  
      }
      

    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.
      #include <iostream>
      using namespace std;
      void main()
      {
         int m,y,d,c,f;
       
         cout << "please enter the month day and year" << endl;
         cout << "like 6 10 1998 :";
         cin >>  m >> d >> y;
       
         m-=2;                           // Subtract two from month?
         if (m<=0) {                     // Prior year?
           m+=12;                        // adjust month 
           y--;                          // adjust year
         }
         c=y/100;                        // Extract century
         y%=100;                         // extract year in century
       
         f = ((int)(2.6*m-0.2) + d + y + (y/4) + (c/4) - 2*c)%7; // Zellers
         
         f+= f<0 ? 7 : 0;                // fix for negative number.
       
         switch(f) {
             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;
         }
      }