Objectives
By the end of this lesson you will be able to:
- Understand how to implement decision making abilities in your programs.
- Understand how to write logical expressions using comparison and conditional operators.
- Create an if clause
- Create an if-else clause
- Create a nested if clause
- Create a switch block
- Create a program that takes input from a user
- Convert variables of one data type to another data type
Decision Structures
Decision structures introduce decision-making ability into a program. They enable you to branch to different sections of the code depending on the truth value of a Boolean expression. In this lesson we will examine the if statement, the if-else statement, and the switch statement.
In computer science, conditional statements, conditional expressions and conditional constructs are features of a programming language, which perform different computations or actions depending on whether a programmer-specified boolean condition evaluates to true or false.
Visual Studio Solution for Tutorial 9
Boolean Expressions
In computer science, a Boolean expression is
an expression in a programming language that produces a Boolean value when
evaluated, i.e. one of true or false.
There are two groupings of boolean expressions:
- Comparison operators
- Conditional operators
Boolean Comparison Operators
Boolean comparison operators are used in boolean expressions to indicate the type of comparison that should be performed on the operands. For example if the value of two variables A and B are both set to the integer value of 3,
bool x;
int A = 3;
int B = 3;
when using the comparison operator the following expression returns true.
x = A == B //true
However, if you used the not equal operator the expression would return false.
x = A != B //false
The table below displays each of the boolean comparison operators along with a sample expression and the result of that expression.
Operator |
Category |
Example Expression |
Result |
== |
Binary |
var1 = var2 == var3; |
var1 is assigned the value true if var2 is equal to var3, or false if otherwise. |
!= |
Binary |
var1 = var2 != var3; |
var1 is assigned the value true if var2 is not equal to var3, or false otherwise. |
< |
Binary |
var1 = var2 < var3; |
var1 is assigned the value of true if var2 is less than var3, or false otherwise. |
> |
Binary |
var1 = vars > var3 |
var1 is assigned the value of true if var2 is greater than var3, or false otherwise. |
<= |
Binary |
var1 = var2 <= var3 |
var1 is assigned the value of true if var2 is less than or eqaul to var3, or false otherwise. |
>= |
Binary |
var1 = var2 >= var3 |
var1 is assigned the value of true if var2 is greater than or equal to var3, or false otherwise. |
Boolean Conditional Operators
Boolean conditional operators are used in boolean expressions to indicate the conditions that should be applied on the operands (you can think of it applying a filter to the expression). For example if the value of two variables A and B are both set to the integer value of 3,
bool x;
bool A = true;
vool B = false;
when using the conditional "and" operator the following expression returns false because the only way it evaluates to true is if both variables had the value of true.
x = A && B //false
However, if you used the conditional or operator the expression would return true because only one of the two variables need be true for the expression to be evaluated to true.
x = A || B //true
The table below displays each of the boolean conditional operators along with a sample expression and the result of that expression.
Operator |
Category |
Example Expression |
Result |
&& |
Binary |
var1 = var2 && var3; |
var1 is assigned the value true if var2 and var3 are both true, or false if otherwise (logical AND). |
|| |
Binary |
var1 = var2 || var3; |
var1 is assigned the value true if either var2 or var3 (or both) is true, or false otherwise (logical OR). |
⇑ Table of Contents
The if
Statement
The if statement will execute a given sequence of statements only if the corresponding Boolean expression evaluates to true. Sometime in your programs, you will want a sequence of statements to be executed only if a certain condition is true.
In C#, you can do this by using the if
, else-if
, or else
statements. Let's see how this works in code starting with the if statement.
- Create a new solution in Visual Studio and name it DecisionStructures.
- Choose the C# Console Application template and type IfStatement for the project name
- Click OK to create the new project.
- Once the new project appears in the Solution Explorer window, right-click on the title of the new IfStatement project
- Choose Set to StartUp in the context menu that appears. What this does is configures Visual Studio to run your new project the next time you choose
Without Debugging from the Debug menu (Ctrl + F5).
In the Source code window of your new IfStatement project select all of the template code and replace it with the following code:
using System;
namespace IfStatement
{
class Program
{
static void Main(string[] args)
{
int number1 = 10;
int number2 = 20;
if(number2 > number1)
{
Console.WriteLine("number2 is greater than number1");
}
}
}
}
Analyzing the code inside of the Main method we see that two integer variables, number1
and number2
are declared and assigned the values of 10
and 20
respectively. These two declarations are followed by an if
statement which consists of the keyword if
followed by a conditional expression enclosed in parenthesis. If the conditional expression evaluates to true
then the code statement inside the curly braces will be processed. If the conditional expression evaluates to false
, the statement inside the curly braces is ignored and the program ends.
This code is functionally equivalent to this flowchart:
A Nested if Statement
A nested if statement is exactly what it sounds like it is, one if statement nested inside of an outer if statement.
To create your own Visual Studio project which demonstrates this concept, do the following:
- Open your Lesson1 solution in Visual Studio
- Add a new Console Application project to the Lesson1 solution and name it NestedIf.
- Right-click on the newly added HandlingExceptions project and choose Set as StartUp Project from the context menu that appears.
- Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
- Type the following code into the Source code window for your NestedIf project and then press CTRL + F5 to run your NestedIf project code without debugging.
using System;
namespace NestedIf
{
class Program
{
static void Main(string[] args)
{
int number1 = 10;
if(number1 > 5)
{
Console.WriteLine("number1 is greater than 5");
if(number1 < 20)
{
Console.WriteLine("number1 is less than 20");
}
}
}
}
}
In this example after the declaration of an integer number1 which is assigned a value of 10, the conditional expression number1 > 5 is evaluated, since number1 is greater than 5, in other words the conditional expression evaluates to true,then the Console.WriteLine statement is executed displaying the text string "number1 is greater than 5" on a device's screen and then the next conditional expression, number1 < 20, is evaluated and since this condition is also true then the next Console.WriteLine statement is executed as well display the text string "number1 is less than 20" on the device's screen.
If we change the number1 declaration in our example to be assigned a value less than 5 then neither of the Console.WriteLine statements would be executed because once the outer if statement is evaluated to false none of the code inside the outer if statement's code block would be executed including the nested if statement.
⇑ Table of Contents
The else-if
Statement
The else-if statement allows your program to perform one action if the Boolean expression evaluates to true and a different action if the Boolean expression evaluates to false.
To create your own Visual Studio project which demonstrates this concept, do the following:
- Open your Lesson1 solution in Visual Studio
- Add a new Console Application project to the Lesson1 solution and name it ElseIfStatement.
- Right-click on the newly added HandlingExceptions project and choose Set as StartUp Project from the context menu that appears.
- Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
- Type the following code into the Source code window for your ElseIfStatement project and then press CTRL + F5 to run your ElseIfStatement project code without debugging.
using System;
namespace ElseIfStatement
{
class Program
{
static void Main(string[] args)
{
int n = 10;
if (n < 10)
{
Console.WriteLine("n is less than 10");
}
else if (n < 20)
{
Console.WriteLine("n is less than 20");
}
else if (n < 30)
{
Console.WriteLine("n is less than 30");
}
else
{
Console.WriteLine("n is greater than or equal to 30");
}
}
}
}
else-if statements are process in order if the, the first conditional expression that evaluates to true will have its code block run and all other conditional expressions and their code blocks are ignored. In the above example if the first three conditional statements evaluate to false then the statement block for the else statement
The else
Statement
The else statement allows your program to have a catch-all block of code that it will run if the if and all of the else-if expressions have evaluated to false. With an else statement you simply type the word else
followed by a set of curly braces containing the code you want to have run in case all-else fails, as shown in the code example above.
The flowchart equivalent of our if else-if else statement is shown in the flowchart below.
⇑ Table of Contents
The switch
Statement
A switch statements allows for multi-way branching. In many cases, using a switch statement can simplify a complex combination of if-else statements.
The switch statement consist of the keyword switch followed by an expression in parenthesis, followed by a switch block. The switch block can include one or more case statements or a default statement. When the switch statement executes, depending on the value of the switch expression, control is transferred to a matching case statement. If the expression does not match any of the case statements, the control is transferred to the default statement. The switch expression must be surrounded by parenthesis. Here is a dissection of our sample code to help identify these key components of the switch statement.
To create your own Visual Studio project which demonstrates this concept, do the following:
- Open your Lesson1 solution in Visual Studio
- Add a new Console Application project to the Lesson1 solution and name it SwitchStatement.
- Right-click on the newly added SwitchStatement project and choose Set as StartUp Project from the context menu that appears.
- Click anywhere in the Source code editor window and pres Ctrl + A on your keyboard to select all of the template code in your new project, and then press Delete.
- Type the following code into the Source code window for your SwitchStatement project and then press CTRL + F5 to run your SwitchStatement project code without debugging.
using System;
namespace SwitchStatement
{
class Program
{
static void Main(string[] args)
{
int result = 0;
int op1 = 10;
int op2 = 20;
string opr = "+";
switch (opr)
{
case "+":
result = op1 + op2;
break;
case "-":
result = op1 - op2;
break;
case "*":
result = op1 * op2;
break;
case "/":
result = op1 / op2;
break;
default:
Console.WriteLine("Unknown Operator");
break;
}
Console.WriteLine($"Result: {result}");
}
}
}
In this code example the TestSwitch method accepts two operands (op1 and op2) and an operator (opr) as parameters which it uses to evaluate one of four possible expressions. The value of the switch expression (opr) is compared to the case statements in the switch block. If there is a match, the statements following the matching case are executed. If none of the case statements match, then control is transferred to the optional default branch.
In this next code example the program is improved by using a while loop to allow for the ability to type in math problems over and over until the user types "x" to end the program. And, the final output statement has been improved to show the entire math problem and the result.
Note that in a switch
block there is a break
statement after each case. The break
statement terminates the switch statement and transfers control to the next statement outside of the switch block. Using a break
ensures that only one branch is executed and helps avoid programming mistakes. In fact, if you specify code after the case statement, you must include a break (or another control transfer statement, such as return
, to make sure that control does not fall through from one case label to another.
However, if no code is specified after the case statement, it is okay for control to fall through to the subsequent case statement.
⇑ Table of Contents
Using Fall Through In A Switch Statement
The following code demonstrates how this might be useful:
using System;
namespace TestSwitchFallThrough
{
class Program
{
static void Main(string[] args)
{
DateTime dt = DateTime.Today;
switch (dt.DayOfWeek)
{
case DayOfWeek.Monday:
case DayOfWeek.Tuesday:
case DayOfWeek.Wednesday:
case DayOfWeek.Thursday:
case DayOfWeek.Friday:
Console.WriteLine("Today is a weekday");
break;
default:
Console.WriteLine("Today is a weekend day");
break;
}
}
}
}
Here, if the value of the expression dt.DayOfWeek is DayOfWeek.Monday, then the first case is matched, but because no code (or a control transfer statement) is specified, the execution will fall through the next statement, and the next, etc, resulting in display of the message "Today is a weekday" in the command window.
You can decide whether to use if-else statements or a switch statement based on the nature of the comparison and readability of the code. For example, the code of the TestIfElse method makes decisions based on conditions that are more suited for use with if-else statements. In the TestSwitch method, the decisions are based on constant values, so the code is much more readable when written as a switch statement.
⇑ Table of Contents
Analyzing the Decision Table for I-P-O
We started Lesson 3 by describing flow charts and decision tables. To wrap up this lesson we'll create a C# program which implements our decision table's four quadrants as shown in Lesson 3, figure 3. In order to dissect a set of code specifications (in this case our decision table) into code it is best to start by examining the program requirements for three things:
- What will be the input of program?
- What will our program need to process?
- What will be the output of our program?
This process of analysis is known as IPO or Input-Process-Output and is commonly used as a starting point for analyzing most specifications in order to convert them to code. So what will be the input of our program? The decision table shown here:
represents the specs for an invoicing application that calculates discount percentages based on the quantity of product purchased." This tells us two pieces of information regarding our IPO analysis. What are they? 1) our program will "calculate" or process discount percentages, and 2) our program will calculate the discount based on knowing the "quantity of product purchased." How will our program know what the quantity of products that have been purchased is? That's right, it will learn this information from input that will be provided by a user; most likely a sales person or a data entry person using our program to enter data from an invoice.
⇑ Table of Contents
Getting Input From the Console
So how does our program receive input from a user in a C# console application? If we think back to your Hello World program we learned that C# has a Console class which has a WriteLine method which allows our program to display text to the screen - however that is only good for output and we need to have our program retrieve input. This is where we need to do some research on the C# Console class. Let's see what we can find on the Microsoft Developer's Network (MSDN) Website by navigating our Web browser to https://msdn.microsoft.com/en-us/library/gg145045(v=vs.110).aspx, this is where we'll find the Microsoft .NET Framework's Class library.
On this page we see a list of namespaces. Let's see, what namespace did we learn the Console class is located in? Correct, the System namespace, let's click on that. Now, we see a list of classes that are in the System namespace, let's scroll down until we find Console and then click on that. Now, we are looking at the details of the Console class. A class we learned previously, is a collection of properties, methods and events, which is another way of saying variables, functions and events. Like variables, properties store data, and like functions, methods do things like output text to the screen — as we know from the
WriteLine method of the Console class. Let's scroll down to the Methods section of the Console class and see what we find.
Interesting, there are a lot of methods that the Console class can perform, and some of those methods have the word "Read" in them. Does it make sense that if WriteLine generates output to the screen that ReadLine will take input from the
screen? Well, guess what, it does, even if it's description does not convey that very clearly to beginning programmers.
⇑ Table of Contents
Displaying Output to the Console
Good to know, however let's not get too far ahead of ourselves. Before we take in the user's input let's begin our program by writing some code that will display instructions which ask our user to input the information our program will need in order to actually do some processing. We'll write this line of code inside of our Main method since we want the display of our instructions to be the first task our program performs. You should already know how to do this because you have already learned how to use the Console.WriteLine method. Just in case you have forgotten, your code should look something like this:
Console.Write("Please enter the quantity of products purchased: ");
We didn't use the WriteLine method here because we did not want our program to generate a line feed, which is what WriteLine does, it moves the cursor to the next line after displaying its text on the screen. We just want to see a flashing cursor at the end of the text we are displaying to the user, so we used Console.Write instead.
Next, let's retrieve the users response to our question. In order to do this we need to do two things:
-
Create a variable to hold our users inputed value.
-
Use the Console's ReadLine method to both retrieve the user's input and at the same time assign the inputed value to our variable.
We will both declare the variable and get the user's input in one elegant line of code like this:
int quantity = Int32.Parse(Console.ReadLine());
What we did there is define a variable named
quantity
as an int
(integer) data type. Then using the assignment operator "=
" we took the user's input using Console.Readline
and at the same time we both converted the user's input, which came in from the Console
as a string
data type, to a 32 bit signed integer using the Parse
method of the Int32
struct
(a struct
is kinda like a class (see Lesson 6 data structures), and assigned the converted value to the quantity
variable. I know you haven't seen the Int32
struct yet, but if you want, you can easily look it up, it's also part of the System
namespace.
Converting String Type to Int32 Type
As you can see the Int32's Parse method accepts a string data type as input and then converts it to a signed 32 bit integer data type - once the input is converted to the correct data type we can safely assign it to our int variable quantity without throwing an error.
Note: You can convert a string to a number by calling the Parse
or TryParse
method found on the various numeric types (int, long, double, etc.), or by using methods in the System.Convert
class; e.g. Convert.ToInt32(number)
.
⇑ Table of Contents
Outputting Results to Console
At this point we can quickly see if our program is working as expected by just adding one more line of code. Next we'll add a Console.WriteLine method and have it display the value of quantity once the user has input it. To do so we'll write this line of code:
Console.WriteLine($"You input a quantity of: {quantity}");
Wow, did you see what we did there? You might recall that on page 16 of your textbook we learned that we can combine a string and a variable in a Console.WriteLine method by using {0}
as a placeholder for our variable inside of our string text followed by a comma and the name of the variable whose value we want displayed in the string instead of the placeholder.
Let's see if our program will run in debug mode by holding down the Control key on our keyboard while at the same time pressing and releasing the F5 key on our keyboard.
Did it work? Could you type in a number and did your program display the value that was input? Be sure to type in a number, if you type in a letter of a symbol your program will throw an error and your program will crash and burn :( - sad smiley face.
Before we go any further, let's get rid of some clutter by removing all but the using System directive from the top of our program. By now you should be able to see that it is the only directive not in gray and for this program, it is the only using directive we are going to need. Here's how your code should look so far:
So, are we having fun yet? I hope so!
So far, we pretty much have our input and output code setup, although we will need to modify the output code just a bit before we're done. Right now what we need to do is handle our process portion of the IPO analysis.
Meaning we need some code that will take the user input and generate the proper output based on our decision table.
⇑ Table of Contents
Analyzing the Decision Table for Process
Let's start with the fact that we are using a decision table as our criteria for our coding logic. Which of the coding structures we learned about in Lesson 1 will work best for representing our decision table? Here is a hint, decision tables are based on a set of conditions. Here is another hint, we are trying to represent a decision table into code. OK, by now hopefully you have guessed we need to use a decision structure to represent our decision table in code. Next question, which type of decision structure will work best? Actually there are two possibilities, a chain of if-else statements or a switch block will both work equally as well in this scenario. So let's pick one, let's go with a series of if-else statements (it's easier for beginners to understand when just starting out).
Let's look at our decision table again to help us determine the conditions we need to incorporate into our if-else statements.
Essentially the way this decision table reads is this:
-
if the customer purchases less than 10 units of a product they get a 5% discount
-
if they purchase less than 50 units of a product they get a 10% discount
-
if they purchase less than 100 units of a product they get a 15% discount
-
otherwise,
any purchase where the number of units is higher than previously stated, their discount is 20%.
Now, let's write this out as pseudo-code:
-
if quantity is less than 10 then discount equals 5%
-
if quantity is less than 50 then discount equals 10%
-
if quantity is less than 100 then discount equals 15%
-
otherwise discount equals 20%
Finally, let's write it out as actual C# code.
if (quantity < 10) discount = 5;
else if (quantity < 50) discount = 10;
else if (quantity < 100) discount = 15;
else discount = 20;
You'll notice I wrote the code in a more compact format than shown in your textbook, but it is C# legal syntactically speaking. The rule with if and if-else statements is that when the "then" portion of the statement is only one
statement then no curly braces are required. In the case of this project example I wrote it this way because I thought it would make it a little easier for you to understand the code.
Now we could put this if-else block of code into our Main method and then move our output statement underneath, but I want to take it one step further to demonstrate how to create your own method and then call the method from our output statement in Main.
⇑ Table of Contents
Creating a Custom Method
We will cover custom methods and custom function in the next lesson. For now, here are some basics you need to know inorder to be able to create a custom method which will enhance the functionality of your program.
In order to create a new method you need to begin writing the code for it outside of the Main method, but still inside of the Program class. The first code line of a method is called its signature and at the very least, a method signature needs to identify two key pieces of information:
-
The type of data it returns when it is done running or if it returns data at all
-
The name of the method followed by a pair of parenthesis
At a minimum a method's signature should look like this: string MyMethod()
For our method we are going to add two more items, 1) an Access Modifier (public, private, internal, or protected) which defines if it can be used by other classes, and 2) a static modifier which defines how it can be used by other classes (see https://msdn.microsoft.com/en-us/library/6tcf2h8w.aspx).
So let's write out our method's signature like this:
private static int CalcualteDiscount(int quantity)
We made our method private, meaning it can only be used within our program. We made it static so we could call it from our Main method without having to create an instance of our class (don't worry about this detail now, just know it simplifies calling our custom method elsewhere in our code). We informed the C# compiler that our method will return a value that is of data type integer - this helps with troubleshooting and debugging. If we had typed void in place of int it would mean that our method does not return any values of any type.
We named our method CalculateDiscount, and in the parenthesis we gave our method the ability to receive data from any code statement which calls it. In this case we are allowing the line of code that calls (invokes) our method to send the our method an integer and internally, our method, will refer to that integer it receives by the name quantity. Do not confuse this with the quantity variable we created in the
Main method. Variables only have local scope, this means they only exist in
the method where they are created, so in any code statements running outside of the Main method, quantity, no longer exists. However, we will take the current value of quantity in the Main method and send that value as a parameter when the code in Main "calls" (invokes) our custom method CalculateDiscount. Once CalculateDiscount receives the value from the calling code, our CalculateDiscount method will then assign that value to another variable which it will refer to internally as quantity; and that quantity variable will be scoped to (only exist in) the CalcualteDiscount method.
Next, we'll write the body of our custom method. We will start by creating a new variable of type int named discount since we will be assigning int values to it with our if-else statements. Then we will add the if-else statements exactly as we wrote them above. And then finally, we will add a keyword return at the end of the method in order to return the value of discount back to the code in Main that called our custom CaluculateDiscount method in the first place. Our custom method will now look like this:
⇑ Table of Contents
Displaying the Results of the Process to the Console
All we have left to do now is to add a new output statement in the Main method so that it calls our custom method, passes the value of its quantity variable to it and format the final output that the user will see.
To do this final step we just need to add a Console.Writeline statement in our Main method just below the existing one which will both call our custom method and pass the value of Main's quantity variable to it. It will look like this:
Console.WriteLine("Your discount is: {CalculateDiscount(quantity)}%");
The only thing new we did there is to use our custom method instead of a variable as the value to be displayed in the Console.WriteLine method. In addition to being a method, CalculateDiscount is being used as a data type; something you'll learn more about much later on. Essentially the way you should see CalcualteDiscount(quantity) is that the Main method is saying to our custom method, "take this value, do something with it, and then return the results back here."
Pretty cool, right!?
Go ahead and run your program in debug mode (Ctrl + F5) and test it out.
⇑ Table of Contents
Using Decision Statements To Calculate Customer Discount
⇑ Table of Contents
Summary
In this lesson you learned how to implement decision making abilities in your programs, write logical expressions using comparison and conditional operators, create an if clause, create an if-else clause, create a nested if clause, create a switch block, create a program that takes input from a user and convert variables of one data type to another data type.