Break statements exit the immediately surrounding loop, but not any loops above that.
while( condition )
{
break; //This jumps out of the loop NOW as if the condition were false
}
//After we break from the loop above, we're HERE
//In the example below, the loop will go through 5 full iterations (0,1,2,3,4) and a partial iteration when i == 5
//Then the loop is over
for(int i = 0; i < 10; ++i)
{
if(i == 5)
{
break;
}
Console.WriteLine(i);
}
//After we break from the loop above, we're HERE
/*
Output from loop above:
0
1
2
3
4
*/Continue statements end the CURRENT loop iteration, and go back to the top of the loop to check the loop condition again.
while( condition )
{
continue; //This ends the CURRENT loop NOW and goes back to the top
}
//In the example below, the loop will go through 5 full iterations (0,1,2,3,4) and a partial iteration when i == 5
//Then 4 more full iterations (6,7,8,9), Then the loop is over
for(int i = 0; i < 10; ++i)
{
if(i == 5)
{
continue;
}
Console.WriteLine(i);
}
/*
Output from loop above:
0
1
2
3
4
6
7
8
9
*/
REMINDER: these keywords do NOT WORK with if statements, only with loops. You can put a break/continue statement INSIDE an if statement, but it will only break/continue the immediately surrounding loop. These statements can be useful from time to time to deal with particular loop issues, but you won’t use them very often.
Switch Statements
We’ve learned that there are two different ways syntactically to make loops: the for loop, and the while loop. But did you know there’s also another way syntactically to write a if/else statements? We can use something called a Switch Statement.
switch( expression )
{
case value1:
{
//do stuff
}
break;
case value2:
{
//do different stuff
}
break;
default:
break;
}What’s going on in the code above? When our program reaches the switch statement, we start looking at each individual case. If the value of a case matches the value of the expression above, we will execute the code for that case. This really is just like if/else, but the syntax is a bit different. Let’s look at an example to really illustrate the differences:
int x = int.Parse(Console.ReadLine());
switch(x)
{
case 0:
{
Console.WriteLine("Yeah they entered zero");
}
break;
case 1:
{
Console.WriteLine("Sure, the user entered '1' ");
}
break;
case 2:
{
Console.WriteLine("They entered '2' let's change it to 15");
x = 15;
}
break;
default:
{
Console.WriteLine("Ugh whatever");
x = 762;
}
break;
}The big difference here is that we’re predicating our different code paths on a variable’s value (or the value of an expression), rather than a condition! That means, we can just put a number, a string, or WHATEVER we want into the switch, and look for different values in our cases.
If the value of x is 0, we will execute the code for case 0, and then break out of the switch statement (just like an if statement!) If the value of x is 1, we will execute the code for case 1, and then break out (just like an else if statement!) If the value of x is 2, we execute case 2, then break. If the value of x is anything other than the cases specified above, we execute the default case (just like an else statement!)
OK, it sort of IS a condition… here’s the equivalent code using if statements:
if(x == 0)
{
Console.WriteLine("Yeah they entered zero");
}
else if (x == 1)
{
Console.WriteLine("Sure, ONE");
}
else if (x == 2)
{
Console.WriteLine("They entered '2' let's change it to 15");
x = 15;
}
else
{
Console.WriteLine("Ugh whatever");
x = 762;
}OK, neat… why does this exist at all? Why not just use if statements? It can be useful to write things using a particular syntax if the syntax itself is a hint to the programmer about the code’s purpose. For example, the following loops are the same:
for(int i = 0; i < 10; ++i)
{
Console.WriteLine("Ah right, the poison");
Console.WriteLine("The poison for Kuzco");
Console.WriteLine("The poison chosen specifically to kill Kuzco");
Console.WriteLine("Kuzco's poison");
Console.WriteLine();
Console.WriteLine("... that poison?");
}
int k = 0;
while(k < 10)
{
Console.WriteLine("Ah right, the poison");
Console.WriteLine("The poison for Kuzco");
Console.WriteLine("The poison chosen specifically to kill Kuzco");
Console.WriteLine("Kuzco's poison");
Console.WriteLine();
Console.WriteLine("... that poison?");
//Increment is all the way down here!
++k;
}However, a for loop is a signal to anyone looking at the code that “this loop will run exactly THIS many times”. You can gather that information by looking at a single line of code! Not so with a while loop; parsing that information takes a bit more time, because you need to scan through the code to find where a counter variable is being modified, or some other variable is being altered to change the loop’s condition. Separating out particular syntax for particular uses can be a way to mentally categorize code, making it easier on yourself when reading/writing programs.
Code Readability/Etiquette
There are many different ways to do the same thing in code. However, it’s useful to stick to certain conventions to ensure you and other programmers can easily understand the code you write. Here are a few guidelines:
Don’t use magic numbers
Oftentimes we will need to use numeric literals in our code, like so:
float CircleCircumference(float radius)
{
return 2.0f * 3.14159f * radius;
}Using 2.0f in the code above is OK, since this inherently part of the formula for circumference. But we might need to use Pi (3.14159f) in a LOT of different places. Instead of having that number just hang out in our code, we could make it a constant, and put it at the class level rather than inside a function:
class WhateverItDoesNotMatter
{
const float pi = 3.14159f;
float CircleCircumference(float radius)
{
return 2.0f * pi * radius;
}
}What is that keyword above? const is a way to create literals in our code that we can refer back to, without accidentally changing their value. This is enforced by the compiler; if we tried to assign a new value to pi, we would get a compile error. But we can still use its value just as we would a variable.
Remove Redundant Code
What’s wrong with the code below?
//pretend that we have an integer
//called x somehwere in our code
if(x == 10)
{
//do thing
}
else if (x != 10)
{
//do something else
}The else/if portion is redundant! You only need an else:
//pretend that we have an integer called x somehwere in our code
if(x == 10)
{
//do thing
}
else
{
//do something else
}You should NOT do this second check “just in case”. There are only two answers to the question: either x IS EQUAL TO 10, OTHERWISE it is NOT, FOR SURE. Don’t overcomplicate things!
Use Descriptive Names and Correct Cases
Remember that circumference function we made earlier? Here’s an example of how NOT to write that code:
const float p = 3.14159f;
float circ(float R)
{
return 2.0f * p * R;
}From glancing at this function, I don’t know what it does, or what the variables represent. It’s much easier to write out the names of variables, and use casing a bit to give hints about what things ARE:
const float pi = 3.14159f;
float CircleCircumference(float radius)
{
return 2.0f * pi * radius;
}The function name is capitalized and uses CamelCase (where separate words in the function name are separated using capitalization). The variable names are lower-case, and longer than a single letter. They’re descriptive enough to let us know what they’re used for in this function.
Indentation and Braces
Remember to indent when you create new scope:
bool RockFact()
{
bool fact = true;
while(true)
{
if(fact)
{
Console.WriteLine("That's a rock fact!");
}
Console.WriteLine("Greg, you're getting us into trouble again!");
}
}If you MUST put a brace on the same line as a while loop or if statement… fine. But I’ll be super grumpy about it!
if(terrible) {
Console.WriteLine("Ugh, this is super ugly code")
}Volcano alert! Volcano alert! Volcano alert! Volcano alert! Volcano alert! Volcano alert!
if(isBad)
Console.WriteLine("Into the chokey with you!")If you write the code above, we’ll visit this website: https://www.volcanoesandearthquakes.com/?hideQuakes=1