Containers that Can House ActiveX Controls

Chapter 7 - Program Control

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Conditional Controls
The C/C++ language supports four basic conditional statements: the if, the if-else, the conditional ?, and the switch. Before a discussion of the individual conditional statements, however, one general rule needs to be highlighted.
Most of the conditional statements can be used to selectively execute either a single line of code or multiple lines of related code (called a block). Whenever a conditional statement is associated with only one line of executable code, braces ({}) are not required around the executable statement. However, if the conditional statement is associated with multiple executable statements, braces are required to relate the block of executable statements with the conditional test. For this reason, switch statements are required to have an opening and a closing brace.
if
The if statement can be used to conditionally execute a segment of code. The simplest form of the if statement is
if (expression)
true_action;
You will notice that the expression must be enclosed in parentheses. To execute an if statement, the expression must evaluate to either TRUE or FALSE. If expression is TRUE, true_action will be performed and execution will continue on to the next statement following the action. However, if expression evaluates to FALSE, true_action will not be executed, and the statement following action will be executed. For example, the following code segment will print the message “Have a great day!” whenever the variable ioutside_temp is greater than or equal to 72:
if(ioutside_temp >= 72)
 printf(“Have a great day!”);
The syntax for an if statement associated with a block of executable statements looks like this:
if (expression) {
 
true_action1;
 true_action2;
 true_action3;
 true_action4;
}
The syntax requires that all of the associated statements be enclosed by a pair of braces ({}) and that each statement within the block must also end with a semicolon (;). Here is an example of a compound if statement:
/*
*   if.c
*   A C program demonstrating an if statement
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*
*/

#include <stdio.h>

int main( )
{
 int inum_As, inum_Bs, inum_Cs;
 float fGPA;
 printf(“\nEnter number of courses receiving a grade of A: ”);
 scanf(“%d”,&inum_As);
 printf(“\nEnter number of courses receiving a grade of B: ”);
 scanf(“%d”,&inum_Bs);
 printf(“\nEnter number of courses receiving a grade of C: ”);
 scanf(“%d”,&inum_Cs);
 fGPA = (inum_As
* 4 + inum_Bs * 3 + inum_Cs * 2)/
        (float) (inum_As + inum_Bs + inum_Cs);
 printf(“\nYour overall GPA is: %5.2f\n”,fGPA);
 if(fGPA >= 3.5) {
   printf(“\nC O N G R A T U L A T I O N S !\n”);
   printf(“You are on the President’s list.”);
 }
 return(0);
}
If fGPA is greater than or equal to 3.5, in this example, a congratulatory message is added to the calculated fGPA. Regardless of whether the if block was entered, the calculated fGPA is printed.
if-else
The if-else statement allows a program to take two separate actions based on the validity of a particular expression. The simplest syntax for an if-else statement looks like this:
if (expression)
 true_action
;

else
 false_action;
In this case, if expression evaluates to TRUE, true_action will be taken; otherwise, when expression evaluates to FALSE, false_action will be executed. Here is a coded example:
if(ckeypressed == UP)
 iy_pixel_coord++;

else
 iy_pixel_coord—;
This example takes care of either incrementing or decrementing the current horizontal coordinate location based on the current value stored in the character variable ckeypressed.
Of course, either true_action, false_action, or both could be compound statements, or blocks, requiring braces. The syntax for these three combinations is straightforward:
if (expression) {
 
true_action1;
 true_action2
;
 
true_action3;
}
else
 
false_action;


if (
expression)
 true_action
;
else {
 
false_action1;
 false_action2
;
 false_action3
;
}

if (
expression) {
 true_action1;
 true_action2
;
 true_action3
;
}
else {
 
false_action1;
 false_action2
;
 false_action3
;
}
Remember, whenever a block action is being taken, you do not follow the closing brace (}) with a semicolon.
The C program that follows uses an if-else statement, with the if part being a compound block:
/*
*   cmpif.c
*   A C program demonstrating the use of a compound
*   if-else statement.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

#include <stdio.h>

int main( )
{
 char c;
 int ihow_many,i,imore;
 imore=1;

 while(imore == 1) {
   printf(“Please enter the product name: ”);
   if(scanf(“%c”,&c) != EOF) {
     while(c != ‘\n’) {
       printf(“%c”,c);
       scanf(“%c”,&c);
     }
     printf(“s purchased? ”);
     scanf(“%d”,&ihow_many);
     scanf(“%c”,&c);

     for(i = 1;i <= ihow_many; i++)
       printf(“
*”);
     printf(“\n”);
   }
   else
     imore=0;
 }
 return(0);
}
This program prompts the user for a product name, and if the user does not enter a ^Z (EOF), the program inputs the product name character by character, echo printing the information to the next line. The “s purchased” string is appended to the product, requesting the number of items sold. Finally, a for loop prints out the appropriate number of asterisks (*). Had the user entered a ^Z, the if portion of the if-else statement would have been ignored and program execution would have picked up with the else setting the imore flag to zero, thereby terminating the program.
Nested if-elses
When if statements are nested, care must be taken to ensure that you know which else action will be matched up with which if. Look at the following example and see if you can figure out what will happen:
if(iout_side_temp < 50)
if(iout_side_temp < 30) printf(“Wear the down jacket!”);
else printf(“Parka will do.”);
The listing was purposely misaligned so as not to give you any visual clues as to which statement went with which if. The question becomes: What happens if iout_side_temp is 55? Does the “Parka will do.” message get printed? The answer is no. In this example, the else action is associated with the second if expression. This is because C matches each else with the first unmatched if.
To make debugging as simple as possible under such circumstances, the C compiler has been written to associate each else with the closest if that does not already have an else associated with it.
Of course, proper indentation will always help clarify the situation:
if(iout_side_temp < 50)
 if(iout_side_temp < 30) printf(“Wear the down jacket!”);
 else printf(“Parka will do.”);
The same logic can also be represented by the alternate listing that follows:
if(iout_side_temp < 50)
 if(iout_side_temp < 30)
   printf(“Wear the down jacket!”);
 else
   printf(“Parka will do.”);
Each particular application you write will benefit most by one of the two styles, as long as you are consistent throughout the source code.
See if you can figure out this next example:
if(test1_expression)
 if(
test2_expression)
   
test2_true_action;
else
 
test1_false_action;
You may be thinking this is just another example of what has already been discussed. That’s true, but what if you really did want test1_false_action to be associated with test1_expression and not test2_expression? The examples so far have all associated the else action with the second, or closest, if. (By the way, many a programmer has spent needless time debugging programs of this nature. They’re indented to work the way you are logically thinking, as was the preceding example, but unfortunately, the compiler doesn’t care about your “pretty printing.”)
Correcting this situation requires the use of braces:
if(test1_expression) {
 if(
test2_expression)
   
test2_true_action;
 }
else
 
test1_false_action;
The problem is solved by making test2_expression and its associated test2_true_action a block associated with a TRUE evaluation of test1_expression. This makes it clear that test1_false_action will be associated with the else clause of test1_expression.
if-else-if
The if-else-if statement combination is often used to perform multiple successive comparisons. The general form of this statement looks like this:
if(expression1)
 
test1_true_action;

else if(
expression2)
 
test2_true_action;

else if(
expression3)
 
test3_true_action;
Each action, of course, could be a compound block requiring its own set of braces (with the closing brace not followed by a semicolon). This type of logical control flow evaluates each expression until it finds one that is TRUE. When this occurs, all remaining test conditions are bypassed. In the preceding example, if none of the expressions evaluated to TRUE, no action would be taken.
Consider the next example and see if you can guess the result:
if(expression1)
 
test1_true_action;

else if(
expression2)
 
test2_true_action;

else if(
expression3)
 
test3_true_action;

else
 
default_action;
This differs from the previous example. This if-else-if statement combination will always perform some action. If none of the if expressions evaluate to TRUE, the else default_action will be executed. For example, the following program checks the value assigned to econvert_to to decide which type of conversion to perform. If the requested econvert_to is not one of the ones provided, the code segment prints an appropriate message.
if(econvert_to == YARDS)
 fconverted_value = length / 3;

else if(econvert_to == INCHES)
 fconverted_value = length
* 12;

else if(econvert_to == CENTIMETERS)
 fconverted_value = length
* 12 * 2.54;

else if(econvert_to == METERS)
 fconverted_value = (length
* 12 * 2.54)/100;

else
 printf(“No conversion required”);
The ?: Conditional Operator
The conditional statement ? provides a quick way to write a test condition. Associated actions are performed depending on whether test_expression evaluates to TRUE or FALSE. The operator can be used to replace an equivalent if-else statement. The syntax for a conditional statement is
test_expression ? true_action : false_action;
The ? operator is also sometimes referred to as the ternary operator because it requires three operands. Examine this statement:
if(fvalue >= 0.0)
 fvalue = fvalue;
else
 fvalue = -fvalue;
You can rewrite the statement using the conditional operator:
fvalue=(fvalue >= 0.0) ? fvalue : -fvalue;
In this situation, both statements yield the absolute value of fvalue. The precedence of the conditional operator is less than that of any of the other operators used in the expression; therefore, no parentheses are required in the example. Nevertheless, parentheses are frequently used to enhance readability.
The following C++ program uses the ? operator to cleverly format the program’s output:
//
//  condit.cpp
//  A C++ program using the CONDITIONAL OPERATOR
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <math.h>                       // for abs macro def.
#include <iostream.h>

int main( )
{
 float fbalance, fpayment;
 cout << “Enter your loan balance: ”;
 cin  >> fbalance;

 cout << “\nEnter your loan payment amount: ”;
 cin  >> fpayment;

 cout << “\n\nYou have ”;
 cout << ((fpayment > fbalance) ? “overpaid by $” : “paid $”);
 cout << ((fpayment > fbalance) ? abs(fbalance - fpayment)) :
                                  fpayment);
 cout << “ on your loan of $” << fbalance << “.”;

 return(0);
}
The program uses the first conditional statement inside a cout statement to decide which string—"overpaid by $" or “paid $”—is to be printed. The following conditional statement calculates and prints the appropriate dollar value.
cout << ((fpayment > fbalance) ? abs(fbalance - fpayment)) :
                                  fpayment);
switch-case
It is often the case that you will want to test a variable or an expression against several values. You could use nested if-else-if statements to do this, or you could use a switch statement. Be very careful, though, because the C switch statement has a few peculiarities. The syntax for a switch statement is
switch (integral_expression) {
case
constant1:
  
statements1;
  
break;
case
constant2:
  
statements2;
  break;
  .
  .
  .
case
constantn:
  
statementsn;
  break;
default:
statements;
}
The redundant statement you need to pay particular attention to is the break statement. In the preceding syntax, if the break statement had been removed from constant1‘s section of code, a match similar to the one used in the preceding paragraph would have left statements2 as the next statement to be executed. It is the break statement that causes the remaining portion of the switch statements to be skipped. Let’s look at a few examples.
Examine the following if-else-if code segment:
if(emove == SMALL_CHANGE_UP)
 fycoord =   5;

else if(emove == SMALL_CHANGE_DOWN)
 fycoord =  -5;

else if(emove == LARGE_CHANGE_UP)
 fycoord =  10;

else
 fycoord = -10;
This code can be rewritten using a switch statement:
switch(emove) {
 case  SMALL_CHANGE_UP:
   fycoord =   5;
   break;
 case  SMALL_CHANGE_DOWN:
   fycoord =  -5;
   break;
 case  LARGE_CHANGE_UP:
   fycoord =  10;
   break;
 default:
   fycoord = -10;
}
The value of emove, in this example, is consecutively compared to each case value looking for a match. When one is found, fycoord is assigned the appropriate value. Then the break statement is executed, skipping over the remainder of the switch statements. However, if no match is found, the default assignment is performed (fycoord = -10). Since this is the last option in the switch statement, there is no need to include a break. A switch default is optional.
Proper placement of the break statement within a switch statement can be very useful. Look at the following example:
/*
*   switch.c
*   A C program demonstrating the
*   drop-through capabilities of the switch statement.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

int main( )
{
 char c=’a’;
 int ivowelct=0, iconstantct=0;

 switch(c) {
   case ‘a’:
   case ‘A’:
   case ‘e’:
   case ‘E’:
   case ‘i’:
   case ‘I’:
   case ‘o’:
   case ‘O’:
   case ‘u’:
   case ‘U’: ivowelct++;
             break;
   default : iconstantct++;
 }
 return(0);
}
This program actually illustrates two characteristics of the switch statement: the enumeration of several test values that all execute the same code section and the drop-through characteristic.
Other high-level languages have their own form of selection (the case statement in Pascal and the select statement in PL/I), which allows for several test values, all producing the same result, to be included on the same selection line. C and C++, however, require a separate case for each. But notice in this example how the same effect has been created by not inserting a break statement until all possible vowels have been checked. Should c contain a constant, all of the vowel case tests will be checked and skipped until the default statement is reached.
The next example shows a C program that uses a switch statement to invoke the appropriate function:
/*
*   fnswth.c
*   A C program demonstrating the switch statement
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

#include <stdio.h>

#define QUIT 0
#define BLANK ‘ ‘

double fadd(float fx,float fy);
double fsub(float fx,float fy);
double fmul(float fx,float fy);
double fdiv(float fx,float fy);
int main( )
{
 float fx,fy;
 char cblank, coperator = BLANK;

 while (coperator != QUIT) {
   printf(“\nPlease enter an expression (a (operator) b): ”);
   scanf(“%f%c%c%f”, &fx, &cblank, &coperator, &fy);

   switch (coperator) {
     case ‘+’: printf(“answer = %8.2f\n”, fadd(fx,fy));
               break;
     case ‘-’: printf(“answer = %8.2f\n”, fsub(fx,fy));
               break;
     case ‘
*‘: printf(“answer = %8.2f\n”, fmul(fx,fy));
               break;
     case ‘/’: printf(“answer = %8.2f\n”, fdiv(fx,fy));
               break;
     case ‘x’: coperator = QUIT;
               break;
     default : printf(“\nOperator not implemented”);
   }
 }
 return(0);
}
double fadd(float fx,float fy)
 {return(fx + fy);}

double fsub(float fx,float fy)
 {return(fx - fy);}

double fmul(float fx,float fy)
 {return(fx
* fy);}

double fdiv(float fx,float fy)
 {return(fx / fy);}
While the use of functions in this example is a bit advanced (functions are discussed in detail in Chapter 8), the use of the switch statement is very effective. After the user has entered an expression such as 10 + 10 or 23 * 15, the coperator is compared in the body of the switch statement to determine which function to invoke. Of particular interest is the last set of statements, where the coperator equals x, and the default statement.
When the user enters an expression with an x operator, the coperator variable is assigned a QUIT value, and the break statement is executed, skipping over the default printf( ) statement. However, if the user enters an unrecognized operator—for example, %—only the default statement is executed, printing the message that the coperator has not been implemented.
The following C++ program illustrates the similarity in syntax between a C switch statement and its C++ counterpart:
//
//  calndr.cpp
//  A C++ program using a switch statement
//  to print a yearly calendar.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//
#include <iostream.h>

int main( )
{
 int jan_1_start_day,num_days_per_month,
     month,date,leap_year_flag;
 cout << “Please enter January 1’s starting day;\n”;
 cout << “\nA 0 indicates January 1 is on a Monday,”;
 cout << “\nA 1 indicates January 1 is on a Tuesday, etc: ”;
 cin >> jan_1_start_day;
 cout << “\nEnter the year you want the calendar generated: ”;
 cin >> leap_year_flag;
 cout << “\n\n The calendar for the year ” << leap_year_flag;

 leap_year_flag=leap_year_flag % 4;
 cout.width(20);
 for (month = 1;month <= 12;month++) {
   switch(month) {
    case 1:
      cout << “\n\n\n” << “ January” << “\n”;
      num_days_per_month = 31;
      break;
    case 2:
      cout << “\n\n\n” << “ February” << “\n”;
      num_days_per_month = leap_year_flag ? 28 : 29;
      break;
    case 3:
      cout << “\n\n\n” << “  March ” << “\n”;
      num_days_per_month = 31;
      break;
    case 4:
      cout << “\n\n\n” << “  April ” << “\n”;
      num_days_per_month = 30;
      break;
    case 5:
      cout << “\n\n\n” << “   May  ” << “\n”;
      num_days_per_month = 31;
      break;
    case 6:
      cout << “\n\n\n” << “  June  ” << “\n”;
      num_days_per_month = 30;
      break;
    case 7:
      cout << “\n\n\n” << “  July  ” << “\n”;
      num_days_per_month = 31;
      break;
    case 8:
      cout << “\n\n\n” << “ August ” << “\n”;
      num_days_per_month = 31;
      break;
    case 9:
      cout << “\n\n\n” << “September” << “\n”;
      num_days_per_month = 30;
      break;
    case 10:
      cout << “\n\n\n” << “ October ” << “\n”;
      num_days_per_month = 31;
      break;
    case 11:
      cout << “\n\n\n” << “November ” << “\n”;
      num_days_per_month = 30;
      break;
    case 12:
      cout << “\n\n\n” << “December ” << “\n”;
      num_days_per_month = 31;
      break;
   }
   cout.width(0);
   cout << “\nSun  Mon  Tue  Wed  Thu  Fri  Sat\n”;
   cout << “—-  —-  —-  —-  —-  —-  —-\n”;

   for ( date = 1; date <= 1 + jan_1_start_day
* 5; date++ )
     cout <<  “ ”;

   for ( date = 1; date <= num_days_per_month; date++ ) {
     cout.width;
     cout << date;
     if ( ( date + jan_1_start_day ) % 7 > 0 )
       cout <<  “   ”;
     else
       cout <<  “\n ”;
   }
   jan_1_start_day=(jan_1_start_day + num_days_per_month) % 7;
 }
 return(0);
}
This application starts by asking the user to enter an integer code representing the day of the week on which January 1st occurs (zero for Monday, 1 for Tuesday, and so on). The second prompt asks for the year for the calendar. The program can now print the calendar heading, and use the year entered to generate a leap_year_flag. Using the modulus operator (%) with a value of 4 generates a remainder of zero whenever it is leap year and a nonzero value whenever it is not leap year.
Next, a 12-iteration loop is entered, printing the current month’s name and assigning num_days_per_month the correct number of days for that particular month. All of this is accomplished by using a switch statement to test the current month integer value.
Outside the switch statement, after the month’s name has been printed, day-of- the-week headings are printed and an appropriate number of blank columns is skipped, depending on when the first day of the month was.
The last for loop actually generates and prints the dates for each month. The last statement in the program prepares the day_code for the next month to be printed.
Combining if-else-if and switch
The next example application uses an enumerated type (enum) to perform the requested length conversions:
/*
*   ifelsw.c
*   A C program demonstrating the if-else-if statement
*   used in a meaningful way with several switch statements.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

typedef enum conversion_type {YARDS, INCHES, CENTIMETERS, \
                             METERS} C_TYPE;
#include <stdio.h>
int main( )
{
 int iuser_response;
 C_TYPE C_Tconversion;
 int ilength=30;
 float fmeasurement;

 printf(“\nPlease enter the measurement to be converted : ”);
 scanf(“%f”,&fmeasurement);

 printf(“\nPlease enter :         \
         \n\t\t 0 for YARDS       \
         \n\t\t 1 for INCHES      \
         \n\t\t 2 for CENTIMETERS \
         \n\t\t 3 for METERS      \
         \n\n\t\tYour response —>> ”);
 scanf(“%d”,&iuser_response);

 switch(iuser_response) {
   case 0  :  C_Tconversion = YARDS;
              break;
   case 1  :  C_Tconversion = INCHES;
              break;
   case 2  :  C_Tconversion = CENTIMETERS;
              break;
   default :  C_Tconversion = METERS;
 }

 if(C_Tconversion == YARDS)
   fmeasurement = ilength / 3;

 else if(C_Tconversion == INCHES)
   fmeasurement = ilength
* 12;

 else if(C_Tconversion == CENTIMETERS)
   fmeasurement = ilength
* 12 * 2.54;

 else if(C_Tconversion == METERS)
   fmeasurement = (ilength
* 12 * 2.54)/100;

 else
   printf(“No conversion required”);

 switch(C_Tconversion) {
   case YARDS       : printf(“\n\t\t  %4.2f yards”,
                              fmeasurement);
                      break;
   case INCHES      : printf(“\n\t\t  %4.2f inches”,
                              fmeasurement);
                      break;
   case CENTIMETERS : printf(“\n\t\t  %4.2f centimeters”,
                              fmeasurement);
                      break;
   default          : printf(“\n\t\t  %4.2f meters”,
                              fmeasurement);
 }

 return(0);
}
This application uses an enumerated type to perform the specified length conversion. In standard C, enumerated types exist only within the code itself (for reasons of readability) and cannot be input or output directly. The program uses the first switch statement to convert the input code to its appropriate C_Tconversion type. The nested if-else-if statements perform the proper conversion. The last switch statement prints the converted value with its appropriate “literal” type. Of course, the nested if-else-if statements could have been implemented by using a switch statement. (A further discussion of enumerated types can be found in Chapter 12.)

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net