Lesson 05: Branches
C/C++ language executes program statements in a sequence. Sometimes we need to alter the flow of the sequence of statements. This is possible using branching statements offered by the C/C++ language. The programmer can jump from one part of the program to another with the help of such statements.
In C/C++, branching statements are classified into two types:
- Conditional branching
- Unconditional branching
Conditional Branching
It includes the statements which work on checking the condition of giving expression to execute the code.
- if statement
- if-else statement
- Nested if statement
- else-if ladder
- switch statement
Unconditional Branching
These statements don't check any condition to execute the code. These statements are pretty much useful to transfer the control from one block to another block over the program.
- break statement
- continue statement
- goto statement
- return statement
5.1 Conditional Branching
In real life, sometimes we need to make some decisions, and based on these decisions, we decide what to do next step. Similar situations arise in the programming also where we need to make some decisions, and based on these decisions, we will execute the next block of code.
if and if-else Statement
if (condition) {
// Statements inside the body of 'if', will be executed if the condition is true
}
If the condition is evaluated as true, the statements inside the body of if are executed. Otherwise, the statements inside the body of if are skipped.
if (condition) {
// Statements inside the body of 'if', will be executed if the condition is true
} else {
// Statements inside the body of 'else', will be executed if the condition is false
}
If the condition is evaluated as true, the statements inside the body of if are executed. Otherwise, the statements inside the body of else are executed.
The conditional operator was invented because a particular construction occurs often in C/C++ programs and it is nice to shorten it. Here an example of the lengthy version of the code:
if (alpha < beta)
min = alpha;
else
min = beta;
The program set min to a smaller value from the alpha and beta variables. This if-else statement requires four lines of code. However, using a conditional operator, the code can be shorted to :
min = (alpha < beta) ? alpha : beta ;
Not all if-else statements can be rewritten using a conditional operator.
The simple way to make a decision in C/C++ is with the if statement. Here is an example of an if statement at work
The Day of February
Here, the if-else statement advances the day from February 28 to either March 1 or February 29, depending on whether the year is a leap year or not:
// if it is Feb 28 and it is a leap year
if ((day == 28) && (month == 2) && (year % 4 == 0) && (year % 100 != 0)) {
day = 29; // then the next day is 29th
} else { // otherwise
day = 1; // next day is March 1st
month = 3;
}
Leap years occur when the year is divisible by 4 (e.g., 1996 is a leap year) but not by 100 (so 1900 is not a leap year, although it is divisible by 4). The remainder operator (%) is used to find if the year is divisible by 4 and by 100 with no remainder. The logical AND operator (&&) makes sure that February 29 occurs only when all the conditions are true at once.
Nested if-else Statement
When an if-else statement is present inside the body of another if or/and else, this is called nested if-else.
if (condition1) {
// Nested if-else inside the body of "if"
if (condition2) {
// Statements inside the body of nested "if"
} else {
// Statements inside the body of nested "else"
}
} else {
// Statements inside the body of "else"
}
else-if Ladder
The else-if ladder statement is useful when checking multiple conditions within the program; nesting of if-else blocks can be avoided using the else-if ladder statement.
if (condition1) {
// These statements would execute if the condition1 is true
} else if (condition2) {
// These statements would execute if the condition2 is true
} else if (condition3) {
// These statements would execute if the condition3 is true
} …
} else {
// These statements will execute if all the conditions return false
}
switch Statement
The switch statement is C/C++'s multiway branch statement. It is used to route execution in one of several different ways. In fact, the switch statement is a special else-if ladder statement in which the conditions are used to compare the same expression with different values. The general form of the statement is:
switch (expression){
case constant1:
// Statements sequence 1
break;
case constant2:
// Statements sequence 2
break;
•
•
•
case constantN:
// Statements sequence N
break;
default:
// Default statements
}
Each statement sequence may be from one to several statements long. The default portion is optional. Both the expression and the case constants must be integer types.
The switch works by checking the expression against the constants.
- If a match is found, that sequence of statements is executed.
- If the statement sequence associated with the matching case does not contain a break, execution will continue on into the next case. Put differently, from the point of the match, execution will continue until either a break statement is found or the switch ends.
- If no match is found and a default case is existent, its statement sequence is executed. Otherwise, no action takes place.
Case Ranges in switch Statements
You all are familiar with switch-case in C/C++, but did you know you can use a range of numbers instead of a single number or character in the case statement?
- That is the case range extension of the GNU C compiler and not standard C or C++.
- A case range specifies a range of values to associate with an individual case label. The case range syntax is:
case low ... high :
A case range behaves exactly as if case labels had been specified for each value in the given range from low to high inclusive. (If low and high are equal, the case range specifies only one value.)
The lower and upper values must conform to the requirements of the C standard. That is, they must be valid integer constant expressions. Case ranges and case labels can be freely intermixed, and multiple case ranges can be specified within a switch statement.
Programming example:
#include
int main()
{
int arr[] = { 1, 5, 15, 20 };
for (int i = 0; i < 4; i++)
{
switch (arr[i])
{
case 1 ... 6:
printf("%d in range 1 to 6\n", arr[i]);
break;
case 19 ... 20:
printf("%d in range 19 to 20\n", arr[i]);
break;
default:
printf("%d not in range\n", arr[i]);
break;
}
}
return 0;
}
The Output:
1 in range 1 to 6
5 in range 1 to 6
15 not in range
20 in range 19 to 20
Error conditions in addition to existing requirements on case labels:
- If the value of low is greater than the value of high, the compiler rejects the code with an error message. (The behavior of other compilers is not consistent, so an error condition is the only way to ensure that programs will not behave differently when compiled by other compilers.)
- If the value of a case label falls within a case range that has already been used in the switch statement, the compiler rejects the code with an error message.
- If case ranges overlap, the compiler rejects the code with an error message.
Note: If an endpoint of a case range is a numeric literal, leave whitespace around the ellipsis (...) to avoid one of the dots being treated as a decimal point.
Example:
case 0...4: // error
case 5 ... 9: // okay
Checking the Range of the Value
The marks obtained by a student in 5 different subjects are input through the keyboard. The students get a division as per the following rules:
- Percentage above or equal to 60 - First Division
- Percentage between 50 and 59 - Second Division
- Percentage between 40 and 49 -Third Division
- Percentage less than 40 - Fail
if statements
#include <stdio.h>
#include <conio.h>
int main()
{
int eng,math,com,sci,ss,total;
float per;
printf("Enter Five Subjects Marks\n");
scanf("%d%d%d%d%d",&eng,&math,&com,&sci,&ss);
total = eng + math + com + sci + ss ;
printf("Toal Marks : %d",total);
per = total * 100.00 / 500;
printf("\n Percentage : %f", per);
if (per >= 60)
printf("1st Division \r\n");
if (per >= 50 && per <= 59)
printf("2nd Division \r\n");
if (per >= 40 && per <= 49)
printf("3rd Division \r\n");
if (per < 40)
printf("Sorry Fail! \r\n");
return 0;
}
else-if Ladder Statements
#include <stdio.h>
#include <conio.h>
int main()
{
int eng,math,com,sci,ss,total;
float per;
printf("Enter Five Subjects Marks\n");
scanf("%d%d%d%d%d",&eng,&math,&com,&sci,&ss);
total = eng + math + com + sci + ss ;
printf("Toal Marks : %d",total);
per = total * 100.00 / 500;
printf("\n Percentage : %f", per);
if(per >= 60) {
printf("\n 1st Division");
} else if(per >= 50) {
printf("\n 2nd Division");
} else if(per >= 40) {
printf("\n 3rd Division");
} else {
printf("\n Sorry Fail");
}
return 0;
}
switch Statement
#include <stdio.h>
#include <conio.h>
int main()
{
int eng,math,com,sci,ss,total;
float per;
printf("Enter Five Subjects Marks\n");
scanf("%d%d%d%d%d",&eng,&math,&com,&sci,&ss);
total = eng + math + com + sci + ss ;
printf("Toal Marks : %d",total);
per = total * 100.00 / 500;
printf("\n Percentage : %f", per);
switch ( (int) per) {
case 60 ... 100:
printf("\n 1st Division");
break;
case 50 ... 59:
printf("\n 2nd Division");
break;
case 40 ... 49:
printf("\n 3rd Division");
break;
dfault:
printf("\n Sorry Fail");
}
return 0;
}
Summary
- else and else if are optional statements, a program having only if statement would run fine.
- else and else if cannot be used without the if.
- There can be any number of else if statement in an "if else-if" block.
- If none of the conditions are met, then the statements in the else block get executed.
Exercises
- Which of the following tests expression(s) for an if statement that determines whether a character ch is a digit; that is, if it is in the rage of character from '0' to '9'.
- if (ch >= 0 && ch <= 9)
- if (ch > 0) else (ch < 9)
- if (ch < '0' || ch > '9')
- if (ch > -1 && ch < 10)
- if (ch >= '0' && ch <= '9')
- if (ch >= 0 && ch <= 9)
- Suppose you want to display "weekday" if a variable day is between 1 (Monday) and 5 (Friday), but you want to display "Saturday" if day is 6 and "Sunday" if day is 7. Which of the following fragment might reasonably be part of the code for this task? Assume day is always in the range of 1 to 7.
- if else ( day == 7) cout << "Sunday";
- else if (day == 6) cout << "Saturday"; else cout << "Sunday";
- else if (day < 6) cout << "Weekday"; else if (day == 6);
- else cout << "Weekday";
- if (dya < 6 ) cout << "Weekday"; else cout << "Saturday";
- If you want to display "Too slow" if speed is less than 40, "Too fast" if speed is greater than 65, and nothing otherwise, it would be appropriate to use:
- a switch statement.
- a series of if statements.
- nested if-else statements.
- an else-if ladder.
- a conditional operator.
5.2 Unconditional Branching
break statement
The break is used to exit from a do, for, or while loop, bypassing the normal loop condition, as shown in Figure 2.1. It is also used to exit from a switch statement.
Figure 2.1: Operation of the break Statement
The break statement is often used to handle unexpected or nonstandard situations that arise within a loop. An example of a break in a loop is shown below:
do {
x = getx();
if ( x < 0 ) break; // terminate if negative
process(x);
} while (!done);
Here, if x is negative, the loop is terminated.
In a switch statement, the break keeps program execution from "falling through" to the next case. (Refer to the switch statement for details.)
A break terminates only the for, do, while, or switch that contains it. It will not break out of any nested loops or switch statements.
continue statement
The continue statement is similar to the break statement in that it is usually activated by an unexpected condition in a loop. However, it returns control to the top of the loop — causing the loop to continue — rather than causing an exit from the loop. Figure 2.2 shows how this looks.
Figure 2.2: Operation of the continue Statement
Whereas the break statement causes an exit from a loop, the continue statement causes part of the loop to be "short-circuited" or bypassed while the loop keeps running. That is, following a continue, control goes back to the top of the loop. For example, the following while loop reads characters from the keyboard until an s is typed:
while (ch = getchar()) {
if (ch != 's')
continue; // read another char
process(ch);
}
The call to process() will not occur until ch contains the character s.
Avoid Division by Zero
Here is an example:
do {
cout << "Enter dividend: ";
cin >> dividend;
cout << "Enter divisor: ";
cin >> divisor;
if (divisor == 0) { // if user error,
cout << "Divisor cannot be zero." << endl;
continue; // go back to top of loop
}
cout << "Quotient is " << dividend / divisor << endl;
cout << "Do another (y/n)? ";
cin >> ch;
} while ((ch != 'n') && (ch != 'N'));
Division by zero is illegal, so if the user enters 0 for the divisor, the control goes back to the top of the loop, and the program prompts for a new dividend and divisor so the user can try again. To exit the loop, the user must answer 'n' or 'N' to the "Do another" question.
goto Statement
In C++, the goto statement is a control flow statement that transfers the program execution to a specific labeled statement. It is generally considered harmful in modern programming practices and is discouraged due to its ability to create spaghetti code. However, there are certain scenarios where the usage of the goto statement might be appropriate.
Basic Structure of a goto Statement:
The goto statement consists of the keyword goto followed by the label of the destination statement. The destination label is preceded by a colon (:).
The goto keyword causes program execution to jump to the label specified in the goto statement. The general form of goto is:
goto label; label:
All labels must end in a colon (:) and must not conflict with keywords or function names. Furthermore, a goto can branch only within the current function — not from one function to another.
Example of a goto Statement:
Consider a program that checks the age of a user and displays a message based on the age:
int age;
cin >> age;
if (age < 18) {
goto underage; // Transfer execution to the "underage" label
}
cout << "Welcome to the program!" << endl;
label: // Label for the "label" statement
cout << "Invalid age entered." << endl;
return;
underage: // Label for the "underage" label
cout << "You must be 18 or older to enter." << endl;
return;
In this example, the goto statement is used to transfer execution to the appropriate label based on the user's age.
Reasons to Avoid the goto Statement:
The goto statement is generally discouraged due to several reasons:
- Readability: Excessive use of goto statements can make code difficult to read and understand, leading to spaghetti code.
- Maintainability: Code with goto statements is often harder to maintain and modify as the logic of the program becomes intertwined and less structured.
- Alternative Control Flow Statements: C++ provides more structured control flow statements, such as if-else, switch-case, and loops, which are generally preferred over goto for better readability and maintainability.
- Debugging Difficulty: Debugging code with goto statements can be challenging as the flow of execution can become unpredictable.
Alternatives to the goto Statement:
In most cases, the goto statement can be replaced with more structured control flow statements, such as if-else, switch-case, and loops. These statements provide a more organized and maintainable approach to controlling program execution.
Appropriate Use Cases for goto:
While the goto statement is generally discouraged, there are a few rare instances where its usage might be appropriate:
- Error Handling: In certain error handling scenarios, the goto statement can be used to jump out of nested loops or complex control flow structures.
- Emulating Break and Continue Statements: In situations where you need to break out of multiple loops or skip iterations, the goto statement can be used in combination with labeled statements to achieve similar functionality.
The goto statement is a powerful tool in C++, but its usage should be carefully considered and used sparingly. In most cases, more structured control flow statements are preferred for better readability, maintainability, and debugging ease. When using the goto statement, it is crucial to document its purpose clearly and ensure that it does not lead to spaghetti code.
Programming Tip for goto Statement
Although the goto fell out of favor decades ago as a preferred method of program control, it does occasionally have its uses. One of them is as a means of exiting from a deeply nested routine. For example, consider this fragment:
int i, j, k;
bool stop = false;
for (i = 0; i < 100 && !stop; i++) {
for (j = 0; j < 10 && !stop; j++) {
for (k = 0; k < 20; k++) {
// ...
if ( (k + 4) == (j + i)){
stop = true;
break;
}
}
}
}
As you can see, the variable stop is used to cancel the two outer loops if some program event occurs. However, a better way to accomplish this is shown below, using a goto:
int i, j, k;
for (i = 0; i < 100; i++) {
for (j = 0; j < 10; j++) {
for (k = 0; k < 20; k++) {
// ...
if ( (k + 4) == (j + i)){
goto DONE;
}
}
}
}
DONE: // ...
As you can see, the use of the goto eliminates the extra overhead that was added by repeated testing of stop in the previous version.
Although the goto as a general-purpose form of loop control should be avoided, it can occasionally be employed with great success.
return statement
The return statement is a control flow statement that terminates the execution of the current function and optionally returns a value to the caller. It is a crucial component of function implementation, allowing functions to communicate results back to the code that invoked them.
Syntax of the return Statement:
The return statement forces a return from a function and can be used to transfer one value back to the calling routine. It has these two forms:
return;
return value;
In C99 and C++, the form of return that does not specify a value must be used only in void functions.
Keep in mind that as soon as a return is encountered, the function will return, skipping any other code that may be in the function.
Also, a function can contain more than one return statemenst.
Purpose of the return Statement:
The return statement serves several important purposes in C++ programming:
- Function Termination: It explicitly ends the execution of the current function, causing the program to exit the function's scope and return to the caller's context.
- Value Passing: It allows functions to communicate results back to the code that invoked them. The returned value can be used in the caller's scope for further processing or decision-making.
- Early Termination: It enables functions to exit prematurely, skipping the remaining code in the function and returning it to the caller. This can be useful for handling error conditions or specific return scenarios.
Types of return Statements:
There are two main types of return statements in C++:
- Void Return: The return statement doesn't require an expression when a function's return type is void. It simply terminates the function's execution without returning a value.
void printHello() { cout << "Hello, world!" << endl; return; // Function terminates without returning a value }
- Value Return: When a function has a non-void return type, the return statement must include an expression that determines the value to be returned. The returned value must be compatible with the function's return type.
int addNumbers(int x, int y) { return x + y; // Function returns the sum of x and y }
In conclusion, the return statement is a fundamental element of C++ programming, enabling functions to communicate results, terminate execution, and facilitate structured program flow. Its proper usage ensures clear and maintainable code, allowing programmers to create well-defined and modular functions.
Examples of return Statement Usage
- Returning a Value:
int square(int num) { return num * num; // Function returns the square of num } int result = square(5); // result = 25
- Early Termination:
int checkInput(int value) { if (value < 0) { cout << "Invalid input: Value cannot be negative." << endl; return -1; // Function terminates early due to invalid input } // Perform additional processing if input is valid return 0; // Function returns 0 indicating valid input }
- Void Return:
void printMessage(string message) { cout << message << endl; return; // Function terminates without returning a value }
Questions
- Write a console application to check whether a given number by the user is EVEN or ODD.
- Write a console application to ask users to input three integer numbers, then display the largest number.
- Write a console application to ask users to input three values for each side of a triangle, then check whether the triangle is valid or not if sides are given.
- The following table shows the salary lists of the ABC company. Write a console application. The system will display their position when the user inputs the salary value.
Salary above \$60,001 \$50,000 ~ \$60,000 \$40,001 ~ \$50,000 \$30,001 ~ \$40,000 below \$30,000 Position Manager Assistant Director Office Clerk Part-Time - Write a temperature-conversion program that allows the user to convert Fahrenheit to Celsius or Celsius to Fahrenheit. Then, carry out the conversion. Use floating-point numbers. Interaction with the program might look like this:
Type 1 to convert Fahrenheit to Celsius,
2 to convert Celsius to Fahrenheit: 1
Enter temperature in Fahrenheit: 70
In Celsius, that's 21.111111 - Write a program to calculate the final price after the discount. The discount rates are as follows.
Customers can enjoy a 10% discount for a total price ≥ \$50 US dollars, a 15% discount for a total price ≥ \$100 US dollars, 20% discount for a total price ≥ \$200 US dollars. The cashier enters the total price of the customer's purchase, and the system displays the payment amount after the discount on the screen.