A Little Intro :
So far, each of the programs in this article has been a series of instructions executed in its physical order. First the statement at the top of the program is executed, then the second statement, then third statement and so on, until the last statement is executed. When working, there are several instances when we have had to make decisions. In other words, the order of execution of statements of a program may change depending upon the specified conditions. You can say that the statements may execute in logical order rather than physical order (the order in which the statements are written in the program). For instance, you need to use a simple condition like:
“If I buy more than 2 shirts then discount will be 20% on each shirt.”
In this case, the result action, that is discount will be 20%, is taken only when the condition, that is number of shirts is more than 2, is evaluated TRUE. Here we have only one condition. However, the conditions could be multiple.
Let we have a program of five statement as
main ()
{
statement-1;
statement-2;
statement-3;
….
Statement-n;
}
Then firstly the statement1 is executed, then the next statement2, statement3, statement4 and in last statement5 would be executed. But what would happen if we want to execute either statement3 or statement4, depending upon certain condition.
The C language provides many control structures to handle conditions and the resultant decisions. In this chapter we will study: the if-else and switch-case constructs. In C, we have relational operators to compare the value of two operands.
Relational Operators
Relational operators are used to compare two operands to test the validity of their relationship. The result of the relational expression is either TRUE or FALSE. However the relational expressions produce the value “1” for TRUE and the value “0” for FALSE. In other words we can say that the type of result is always an int value.
Table-1 shows a list of relational operators.
Precedence of Relational Operators
The relational operators are lower in precedence than arithmetic operators. It means that the expression:
x > y + z
is equivalent to the expression:
x > (y + z)
Parentheses can always be used to override the order of evaluation in an expression. Thus in the following expression
(x > y) + z
the comparison is made first and then the result of the comparison is added to the value of z. The best rule to follow for deciding when to use parentheses is to use them when in doubt. If they make it easier for human to understand the expression, they should be used.
Operator |
Meaning |
< |
Less than |
> |
Greater than |
<= |
Less than or equal to |
>= |
Greater than or equal to |
== |
Equal to |
! = |
Not equal to |
Table 1
Every relational operator is a binary operator. The left-hand side operand of the relational operator is treated as first operand and right side operand as second operand. The operands can have integrals, floating or pointer type.
For example
int x , y ;
x = 5;
y = 7;
x > y results in 0
x < y results in 1
x <= y results in 1
x >= y results in 0
x == y results in 0
x ! = y results in 1
The relational operators are not bound to just comparing variables or constants; we can also compare directly the results of arithmetic expressions. Watch the result of the following expressions:
int x, y ;
x = 10;
y = 15;
Expressions Result
(x+3) < (y-4) 0 (false)
(x+6) > (y+2) 0 (false)
(x+9) <= (y+4) 1 (true)
(x-3) >= (y-10) 1 (true)
(x+6) == (y+6) 0 (false)
(x+5) != (y-1) 1 (true)
As stated earlier, C allows decisions to be made by evaluating a given expression as true or false. The computer’s ability to make decision and execute different sequence of statements is a key factor in its usefulness for solving practical problems. In C, we have decision control structures that are used when a program requires that the computer must choose between two or more actions.
C provides three decision control structures:
- the simple if statement
- the if-else statement
- the switch statement
The Simple if Statement
The syntax of a simple if statement is as:
if (test-condition)
Statement;
Here if is a keyword which is followed by a test-condition. The test-condition consists of relational operators. If the test-condition is TRUE then the Statement is executed; otherwise the statement that follows the if–statement is executed.
The pictorial representation of if-statement is as shown in figure-1
Figure 1
Now let us write the if-statement of the earlier said example, say if I buy more than 2 shirts then discount will be 20% on each shirt. The above example is thus written as:
if (shirts > 2 )
discount = 0.20;
Here the number of shirt is received from the keyboard, then tested using the if-statement.
Following program illustrates the use of simple if statement.
/* Program-cs1.c */
#include
main ()
{
int shirts;
float rate, discount, total_price;
rate = 150.00;
printf("\nEnter the number of shirts = ");
scanf("%d",&shirts);
discount = 0.0;
if (shirts > 2 )
discount = 0.2;
total_price = shirts * rate * (1 - discount) ;
printf("Total price of %d shirts = %f", shirts, total_price) ;
}
Here are sample outputs of this program….
First Run:
Enter the number of shirts = 10
Total price of 10 shirts = 1200.000000
Second Run:
Enter the number of shirts = 2
Total price of 2 shirts = 300.000000
In this we have just one statement, discount = 0.2, as a result of test condition inside the if statement. But sometimes there may be more than one statement inside the if statement and then such set of statement must be enclosed within braces ({ }) as:
if (test-condition)
{
Statement-1;
Statement-2;
Statement-3;
----
----
Statement-n;
}
Here if you do not use the braces then the compiler will execute only Statement-1 if the test-condition results in true and other statements will always execute irrespective of the result of test-condition. The program given below illustrates the execution of multiple statements upon the fulfillment of a test condition.
/* Program-cs2.c */
#include
main ()
{
int number;
scanf("%d", &number);
if (number < 0)
{
printf("\nYou have entered negative number.");
printf("\nPlease enter any positive number.");
}
printf("\nThank you.");
}
In this example, if you enter any negative number during then the following statements are executed first:
You have entered negative number.
Please enter any positive number.
and then
Thank you.
However, if you do not enter a negative number then it will only display the following statement:
Thank you.
Another main point to note here is that there are no restrictions on the positions of braces. You can put them anywhere around this block and this block is indented to the right. It is used just for the convenience of the reader. It will help you read your programs, especially when they get larger and contain many nested blocks.
Here one should remember that the right parentheses of a test condition should not be followed by a semicolon; as the semicolon will itself be conditionally executed. The following statement
if (test-condition) ;
Statement;
is interpreted as:
if (test-condition) ;
Statement;
Thus if you write an if-statement, by mistake, as:
if (shirts > 2 );
discount = 0.2;
The extra semicolon after the condition will end the statement at this point, and the next statement will be always executed. Therefore watch your semicolons more carefully while using if statement.
The if-else Statement
In certain programming environment we come across in such a situation where we want to execute a statement Statement1 if our condition is TRUE and execute a statement Statement2 if our condition is FALSE. In other words, you can say that when taking a decision, there are always two faces to it, that is to do or not to do. This can be achieved by using the complete if-else structure. The syntax of the if-else statement is as:
if (test-condition)
Statement-1;
else
Statement-2;
Here if the test-condition results in TRUE then the Statement1 is executed; otherwise Statement1 is skipped and Statement2 is executed. The pictorial representation of if-else statement is as shown in figure-2
Figure 2
However you can also have a set of statements as results for either the TRUE or FALSE conditions. Like simple if statement, if you have multiple statements in if body and as well as in else body then it is necessary to enclose them within a pair of braces as:
if (test-condition) {
Statement-1;
Statement-2;
Statement-3;
Statement-4;
}
else
{
Statement-5;
Statement-6;
Statement-7;
Statement-8;
}
Like simple if statement, the statements in the else block have been indented to the right just to improve the readability of the code. Following example illustrates the use of the if-else statement.
/* Program-cs3.c */
#include
main ()
{
int number;
scanf("%d", &number);
if (number < 0)
{
printf("\nYou have entered a negative number.");
printf("\nYou should enter a positive number.");
}
else
{
printf("\nYou have entered a positive number.");
printf("\nYou should enter a negative number.");
}
printf("\nThank you.");
}
Now if you enter a number, say –10, the output will be:
You have entered a negative number.
You should enter a positive number.
Thank you.
However, if you enter a number, say 35, the output will be:
You have entered a positive number.
You should enter a negative number.
Thank you.
Nested if-else Structure
There are no restrictions on what the statement in an if-else statement can be. Therefore C provides the facility of using an entire if–else statement within either the body of the if statement or the body of an else statement. This is called as nested if–else statement. The term nesting comes from an analogy to a set of mixing bowls that nest together with smaller ones inside of larger ones. The most general form of two layer-nesting is:
if (test-condition-1)
{
if (test-condition-2)
{
Statement(s);
}
else
{
Statement(s);
}
}
else
{
if (test-condition-3)
{
Statement(s);
}
else
{
Statement(s);
}
}
In this if the test-condition-1 results in true then the if-else statement, which is embedded in if block, is executed and the other if-else statement, which is embedded in else block, is skipped. On the other hand if the test-condition-1 results in false then the if-else statement, which is embedded in if block, is skipped and the other if-else statement, which is embedded in else block, is executed.
The following program puts this logic into action:
/* Program cs4.c */
#include
main()
{
int a,b;
printf("\nEnter first number : ");
scanf("%d", &a);
printf("Enter second number : ");
scanf("%d", &b);
if (a>b)
printf("First number is greater than second number.");
else
{
if (a printf("Second number is greater than first number.");
else
printf( "Both numbers are equal.");
}
}
The following are sample runs for this program:
First Run
Enter first number : 10
Enter second number : 12
Second number is greater than first number.
Second Run
Enter first number : 12
Enter second number : 2
First number is greater than second number.
In this program, the second if–else statement is nested in the first else statement. If the first test-condition, that is a>b, is true then it displays the message
- First number is greater than second number.
If the first test-condition is false, then the second test-condition, that is a
Otherwise it displays the message
Both numbers are equal.
Here an if–statement is placed within the else body of the if–else statement. You can also place an if–else in the if block as well. Note that there is no limit on how deeply the ifs and the elses can be nested. If you are nested more deeply then you should make proper indentation; otherwise it may misguide you and others. In such case you may inadvertently match the wrong if.
Actually the rule is that every else belongs to the last if in the same block. Following program shows this.
/* Program cs5.c */
#include
main()
{
int age;
printf("\n Enter your age : ");
scanf("%d", &age);
if (age <=18) /* first if-statement */
printf("\n You have not yet grown up.");
else /* first else-statement */
if (age <= 35) /* second if-statement */
printf("\n You are a good looking young person.");
else /* second else-statement */
printf("\n You are a nice gentleman");
}
In this program, the second else statement does not belong to first if-statement. Rather than the second else belongs to second if-statement. No doubt, this program would work. But when you will look at this program after some time, you may get confused because the else is matched with the wrong if. Here is the proper indentation of this program.
/* Program cs66.c */
#include
main()
{
int age;
printf("\nEnter your age : ");
scanf("%d", &age);
if (age <=18) /* first if-statement */
printf("\nYou have not yet grown up.");
else /* first else-statement */
if (age <= 35) /* second if-statement */
printf("\nYou are a good looking young person.");
else /* second else-statement */
printf("\nYou are a nice gentleman");
}
Here are some sample outputs of this program….
First Run
Enter your age : 15
You have not yet grown up.
Second Run
Enter your age : 30
You are a good looking young person.
Third Run
Enter your age : 50
You are a nice gentleman
The if-else-if Ladder
When there are several different conditions are evaluated from the top down, and whenever a condition is evaluated TRUE, the corresponding statement (or set of statements) is (or are) executed and the rest of the construct is skipped. This construct is referred to as the if-else-if ladder. The general syntax of if-else-if ladder is as:
if (test-condition-1)
Statement-1;
else if (test-condition-2)
Statement-2;
else if (test-condition-3)
Statement-3;
else if (test-condition-4)
Statement-4;
….
else if (test-condition-n)
Statement-n;
Since C does not offer an else-if statement, therefore one should not confuse that the else-if is another reserved, rather than it is just another refined form of nested if-else statement. We know that C is a free-form language, therefore their conditions and their associated statements are just shown in a well-organized way in order to make a program into an easy–to–read format.
Now look at the following program. It is just another way of writing program-cs6.c
/* Program cs7.c */
#include
main()
{
int age;
printf("\nEnter your age : ");
scanf("%d", &age);
if (age <=18)
printf("\nYou have not yet grown up.");
else if (age <= 35)
printf("\nYou are a good looking young person.");
else
printf("\nYou are a nice gentleman");
}
This revised format is much clearer than earlier one. Here this entire structure still counts as one statement and lets you choose one among several alternatives.
Combining Several Relational Expressions
The logical operators are used to combine relational expressions together using the rules of formal logic. Table-2 lists three logical operators:
Operator |
Meaning |
&& |
AND |
|| |
OR |
! |
NOT |
The first two operators, && and ||, allow two or more relational expressions to be combined in an if statement. Let us see a simple program that illustrates the use of the logical operators.
The following program displays whether a given year is a leap year or not.
/* Program - cs8.c */
#include
main()
{
int year;
printf("\nEnter a year : ");
scanf("%d", &year);
if ((year%4==0) && (year%100 != 0) || (year % 400 == 0))
printf("%d is a leap year.\n", year);
else
printf("%d is not a leap year.\n", year);
}
Here are some sample outputs of this program….
First Run:
Enter a year : 1600
1600 is a leap year.
Second Run:
Enter a year : 1900
1900 is not a leap year.
The switch Statement
We know that the nested if–elses provides the facility of making a choice among several alternatives. The limitation of using nested if–elses is that you have to carefully match the corresponding ifs and elses and also the corresponding pair of braces. However C provides another decision control statement, a switch statement, that allows you to handle multiple choices, such as menu options. The decision is based upon the current value of the expression which is specified with the switch statement.
The syntax of the switch statement is as:
switch (integer-expression)
{
case label1 :
statement(s);
case label2 :
statement(s);
case label3 :
statement(s);
….
case labeln :
statement(s);
default :
statement(s);
}
The switch structure starts with the switch keyword followed by one block, which contains different cases. The keyword switch is followed by an integer expression. The integer-expression must be any expression that yields an integer value. It could be any integer constant or an expression that reduces to an integer value. The values followed by the keyword case are labels. Each label must be an integer or a character constant. Also each label must be different from all the others.
When a program encounters a switch statement, the integer-expression is evaluated first. If it is evaluated as “label1”, the “case label1 :” is executed. If it is evaluated as “label2”, the “case label1 :” is skipped and “case label2 :” is executed and so forth. Whenever it finds the suitable match, the statements following that case labels gets executed and all subsequent cases and default statements as well unless you explicitly direct it otherwise. However, if the value of the integer expression does not correspond to any case, the default case is executed. If the default case is omitted, and no case match is found, none of the statements in the switch body is executed.
The pictorial representation of the switch statement is as shown in figure-3
Figure 3
Here is a simple program of a switch statement.
/* Program cs9.c */
#include
main()
{
int n;
printf("\nEnter a number : ");
scanf("%d", &n);
switch (n)
{
case 1:
printf("\nYou entered 1.");
case 2:
printf("\nYou entered 2.");
case 3:
printf("\nYou entered 3.");
case 4:
printf("\nYou entered 4.");
default :
printf("\nYou have not entered 1, 2, 3 or 4.");
}
}
The output of this program is
Enter a number : 3
You entered 3.
You entered 4.
You have not entered 1, 2, 3 or 4.
From this output it is clear that whenever it finds a match, it then sequentially executes all the statements following that line, including the default as well, even though a match has already taken place. The default case may or may not be included, depending on the program’s needs. However, the default case can appear anywhere within the switch statement. If you do not want to execute all the subsequent cases and the default then use a break statement. The break statement skips the remaining statements of the switch statement and transfers the control to the statement following the switch statement.
C provides the facility of making decisions by using three selection control statements: the simple if statement, the if-else statement and the switch statement. The if-statement allows you to take different paths through a program based on the test condition. The test condition contains relational and logical operators. A test condition is evaluated and is assigned the value 1 if the condition is true or 0 if the condition is false.
The if-else allows you to choose between two courses of action. There can be simple or compound statement with if and else clause. There can be an if-else statement within another if statement, that nested if statement.
The switch statement is a multi-way selection statement. It allows the program to choose among a set of alternatives. The selection is based upon the current value of the expression, which is specified within the switch statement. This expression should yield an integer value because it can not be used with real values. The break statement terminates the switch statement and transfers the control outside the switch statement. If the break is omitted then the statements for subsequent cases will also be executed, even though a match has already taken place.