In this chapter, we are going to look at conditional statements and how we control the flow and direction of our programs. The ability to control the flow of your program and letting it make decisions like this is one of the most important features of computer science to the programmer.
Without a conditional statement such as the ‘if’ statement, programs would run almost the same way every time, following only one path and having only one single outcome.
If statements, allow the flow of the program to be changed conditionally. If condition A is true, execute this code, else it is not true, execute this other code.
A good way to picture this is to see a flow chart. Look at the flowchart below that describes what to do before heading outside. Here, a 1 represents true, or yes, and the data moves in the direction of that arrow, or if 0, then no or false, and instead we follow the arrow through that path.
Whether the first condition is ‘Raining?’ is met, determines what we do, and from there, whether or not we can find our coat.
The ‘Look for a coat’, to ‘Find it?’ query, acts as something of a loop until we find our coat (bear that in mind, you will need it in a few chapters). If that condition is met, we can pass to the next step before we finally reach the end. Otherwise, we may completely bypass this all together if it is not raining, and we leave our coat behind. If the condition is true, we follow the path of the 1, and if false, we follow the path of the 0.
Lets look at the syntax for an ‘if’ statement
if(condition)
{
//Code that will executive if condition returns true
}
else
{
//Code that will executive if condition returns false
}
By this point, you have no doubt noticed ‘else’ in the ‘if’statement. If an ‘if’ statement evaluates to false, it is good practice, but not all ways needed, to have a default case. Essentially, there is some code for the system to execute rather than the code executed when the statement runs true. This is effectively the purpose of the ‘else’ statement.
Remember that whenever we see ( ) we know we are dealing with a function, and whatever was placed inside is its parameters. Well, whenever we find { }, we know that whatever is within these parentheses is the scope of whatever came before it. After the ‘if’ statement, we use these to say, ‘if condition’ is met, execute the code between these parentheses. The code within the parentheses ‘{ }’ below the ‘if’ and before the ‘else’, only executes if the ‘else’ is true, and likewise, the code within the parentheses ‘{ }’ below the ‘else’, is in the scope of the ‘else’, and thus only executes if the condition is not met.
This is also true of the main function, we use these parentheses to define its scope also.
Try to write this simple program and run it to find whether or not we are using an odd or even number.
#include <stdio.h>
int main() {
int num;
printf("Enter an integer: ");
scanf("%d", &num);
// True if num is perfectly divisible by 2
if(num % 2 == 0)
printf("%d is even.", num);
else
printf("%d is odd.", num);
return 0;
}
We can even place ‘if’ statements inside other ‘if’ statements for a continued branch of paths and conditions. These are called a nested statement. This is especially useful if you want to check the condition once one condition has already been met, as we demonstrated before, checking if we could find our coat once the condition ‘raining’ had already returned true.
if(condition)
{
if(anotherCondition)
{
//Code that will executive if condition and anotherCondition return true
}
else
{
//Code that will executive if condition returns true but anotherCondition
returns false
}
}
else
{
//Code that will executive if condition returns true
}
There will be times you must nest code like this, especially in games, with lots of paths and branches based on the user input or actions, as you can imagine this can become rather complicated very quickly.
Early computer games were often story-based and inspired by role-playing adventure books, where the player would be given a choice, and then depending on the choice, it would define how they progressed. In the books, the player would have skipped to a specified page, in these early computer games, an ‘if’ statement was executed that changed their fate.
You walk along a dark passageway, in the distance, you hear the chattering whispers of unknown evil, and acrid aroma flows into your nostrils, surely these are the cries of the damned and undead. Clutching your sword tightly in the palm, you collect yourself and contemplate whether to proceed.
If you happened to chose yes, then the story does not end so well, but say you chose to turn back, you would have discovered a secret passage that contained a magic Armour set. Each choice would have been represented by a series of nested, or as I like to say ‘branching’ if statements.
So, lets write another simple code, but this time incorporate a nested statement.
#include <stdio.h>
int main() {
int year;
printf("Enter a year: ");
scanf("%d", &year);
if (year % 4 == 0) {
if (year % 100 == 0) {
// the year is a leap year if it is divisible by 400.
if (year % 400 == 0)
printf("%d is a leap year.", year);
else
printf("%d is not a leap year.", year);
} else
printf("%d is a leap year.", year);
} else
printf("%d is not a leap year.", year);
return 0;
}
There are three kinds of ‘if’ statements, thus far we have covered two. What if we require more than than just two options? More complex paths to follow and diversity to our decision-making program? This is when we use the ‘else if’ statement, its syntax is very simple.
Nested If statements: You can use one if or else if statement inside another if or else if statement(s). |
Else…if statement: An if statement can be followed by an optional else statement, which executes when the Boolean expression is false. |
if(condition)
{
// Statements inside body of if
}
else if (anotherCondition)
{
//Statements inside body of else
}
else if (YetAnotherCondition)
{
//Statements inside body of else
}
else
{
//Statements inside body of else
}
We can use as many ‘else if’ statements as we like and programming a near-infinite number of paths for all our possibilities. We can freely place ‘else if’ and ‘if’ statements inside the scope of ‘else’ statements to have infinitely complex algorithms and possibilities of logic.
Now we have our paths, its time to understand how we set the conditions.
Variables may be used to represent the current state of elements that we are interested in. Operations allow us to then define relationships between those variables. Relational operators in c programming are used for specifying the relation between two operands such as greater than, less than, and equals. They are also referred to as ‘Comparison Operators’ for this very reason. Most of these, you will have seen before.
== | If the values of two operands are equal or not. If yes, then the condition becomes true. | (1 == 2) is not true. |
!= | If the values of two operands are equal or not. If the values are not equal, then the condition becomes true. | (1 != 2) is true. |
> | If the value of left operand is greater than the value of right operand. If yes, then the condition becomes true. | (1 > 2) is not true. |
< | If the value of left operand is less than the value of right operand. If yes, then the condition becomes true. | (1 < 2) is true. |
>= | If the value of left operand is greater than or equal to the value of right operand. If yes, then the condition becomes true. | (1 >= 2) is not true. |
<= | If the value of left operand is less than or equal to the value of right operand. If yes, then the condition becomes true. | (1 <= 2) is true. |
In this exercise, we are going to expand our use of the relational operations and with a simple code to decide if the user is old enough to vote.
#include <stdio.h>
void main()
{
int voteAge;
printf("Input the age of the candidate : ");
scanf("%d",&voteAge);
if (voteAge<18)
{
printf("Sorry, You are not eligible to caste your vote.\n");
printf("You would be able to caste your vote after %d year.\n", 18-voteAge);
}
else
printf("Congratulation! You are eligible for casting your vote.\n");
}
Now let’s try another exercise with a more complex set of if statements, that use all the relational operators. Type out the following code into code-blocks and run it.
#include <stdio.h>
main() {
int a = 21;
int b = 10;
int c ;
if( a == b ) {
printf("Line 1 - a is equal to b\n" );
} else {
printf("Line 1 - a is not equal to b\n" );
}
if ( a < b ) {
printf("Line 2 - a is less than b\n" );
} else {
printf("Line 2 - a is not less than b\n" );
}
if ( a > b ) {
printf("Line 3 - a is greater than b\n" );
} else {
printf("Line 3 - a is not greater than b\n" );
}
/* Lets change value of a and b */
a = 5;
b = 20;
if ( a <= b ) {
printf("Line 4 - a is either less than or equal to b\n" );
}
if ( b >= a ) {
printf("Line 5 - b is either greater than or equal to b\n" );
}
}
Logical operators allow us to define the condition, beyond just a relationship and allow us to test multiple relationships in a single condition. These operators are all forged from Boolean Algebra (remember that?!).
Please Note: You do not need to know Boolean algebra to take this course, but I advise you to read my summary of it in chapter one or perhaps refresh your understanding of it to help in clarity!
Operator | Description | Output |
---|---|---|
&& | The first operation is Logical AND and it means pretty much what it does in plain English. So, for instance, I may state “If it’s sunny outside Logical AND I have completed my work then I will go for a run.” To represent this in Boolean Algebra I may say that: | (1 && 0) is false. |
|| | Logical OR is also the same as how we would use it in plain English. It means that if either of the two variables is True then the result is True. For instance, I could say that “I will get home early from work if I get to leave early Logical OR the traffic is good”. | (1 || 0) is true. |
! | Called Logical NOT Operator. It is used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make it false. Now that sounds little complicated, but try applying a not to action in English language such as ‘do’ which represents 1, and then apply a not to it ‘do not’ and it represents the opposite, 0. This can float around, you may see it before a = sign as before, before a < to reverse it to a >. It is patty diverse, | !(1 && 0) is true |
We place these inside the parameters of the if statement. Here is the syntax:
if (conditionA == true && conditionB == true )
{
// Statements inside body of if
}
else if !(conditionA == true && conditionB == true )
{
//Statements inside body of else
}
else if (conditionA == true || conditionB == true )
{
//Statements inside body of else
}
else
{
//Statements inside body of else
}
Use the logical operators to write a simple program that checks if the user has input a vowel or consonant.
#include <stdio.h>
int main() {
char c;
int lowercase, uppercase;
printf("Enter an alphabet: ");
scanf("%c", &c);
// evaluates to 1 if c is either lowercase or uppercase
if ((c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');)
printf("%c is a vowel.", c);
else
printf("%c is a consonant.", c);
return 0;
}
Repeat exercise two, but rather than using nested statements, use Logical Operators.
Experiment with adding the logical not ‘!’ into the Exercise Three, and observe the differences this has made to how your code executes.
Congratulations on finishing this lengthy and difficult chapter!
A lot of information was covered here, but you should now be able to program your basic programs, which take user input and do something with it! You are also most of the way through the core concepts, and well on your way into flourishing into an adept programmer. Be proud of yourself!
This course is provided for free, as we at Devoke believe all education should be. However, if you enjoy the course, we are always grateful for support and donations to Patreon to ensure we can continue providing resources for free.