By request, here is another installment to my C++ tutorial.
Lesson 2: Learning Conditionals and Variables with a Calculator
As per my usual format, I'm going to post some code, and then discuss the language features it utilizes. This is going to be a fairly simple program: a 4-function calculator that reads a command in two steps. The first step will read in the command for the function, and the second step will read in the 2 numbers that are to be applied to that function. For simplicity, this program will only deal with integer values. If you give it something other than an integer value, it will get mad and throw a chair at you and steal your lunch money. So, don't do it.
#include <iostream>
#include <string>
using namespace std;
int main() {
while(true) {
cout << "Enter the function you wish to use (add, sub, mul, or div): ";
string function;
cin >> function;
cout << endl;
int a, b;
cin >> a >> b;
if(function == "add") {
cout << a << " + " << b << " = " << a+b << endl;
}
else if(function == "sub") {
cout << a << " - " << b << " = " << a-b << endl;
}
else if(function == "mul") {
cout << a << " * " << b << " = " << a*b << endl;
}
else if(function == "div") {
cout << a << " / " << b << " = " << a/b << endl;
}
else {
cout << "That is not a valid option." << endl;
}
cout << endl;
}
return 0;
}
If you're a beginner with no knowledge other than what you learned in Lesson 1, you're probably staring at this code, wondering what magic I just used. Well, do not worry, because I'm about to teach you. It's time to learn some spells.
Piece 1: Including and Using
#include <iostream>
#include <string>
using namespace std;
Like in Lesson 1, we're including the iostream header and telling the compiler we want to use the standard namespace. But, this time, we're also including the string header! It lets us do cool things like work with strings (who would have guessed?), which are defined as sequences of characters.
Well, that exposition isn't very helpful without a basic knowledge of data types in C++, so let's get that out of the way. C++ has 8 (or 9; more on that later) data types that are called primitive data types. They are called primitive because they are defined by the compiler, and don't need any external libraries to use them. Those 8 are, in order of size: bool, char, short, int, long, float, double, and long double. In addition, there are two special modifiers that apply exclusively to these data types, signed and unsigned. Signed means that the data type can represent negative values, while unsigned means it cannot. So, now for some definitions:
(all ranges are inclusive)
A bool represents a boolean value. It can hold only two values, true and false. Boolean means just that, something that is either true or false.
A char represents a single character, like 'a' or '0'. It acts like an integer type, in that it holds integral values, but those integral values are used to represent characters according to the ASCII standard. Don't worry too much about it. It can hold values from -128 to 127 signed, or 0 to 255 unsigned. The default for a char is unsigned.
A short is a type of integer. It can hold numerical values from -32768 to 32767 if signed, or from 0 to 65535 if unsigned. The default is signed.
An int is another type of integer. It can hold numerical values from -2147483648 to 2147483647 if signed, or from 0 to 4294967295 if unsigned. The default is signed.
A long is yet another type of integer. Depending on your computer, it can either act identical to an int, or have a range from -9223372036854775808 to 9223372036854775807 (signed) or 0 to 18446744073709551615 (unsigned). More on this in a later tutorial. The default is signed.
Floats, doubles, and long doubles are so complicated to explain that an entire lesson needs to be devoted to them if I'm going to have any success explaining them. So, for the moment, feel free to pretend they don't exist, if it helps you learn better.
At this point, many of you are probably asking your monitors, "What about strings? Didn't you say something about them earlier? Where do they fit in?" Well, string is another data type, but it is not a primitive data type. Instead, we refer to string as being a class. A class is like a primitive data type in many ways, but has extra abilities. It's like a super data type. In the world of C++, primitive data types are normal people, going about their everyday lives, while classes are the superheroes (and super-villains, in some cases!), with their special abilities. That's silly, I know. But, it is a nice way to think about it for right now.
Alright, now that we know enough about data types for the moment, let's (finally) go back to the code.
Piece 2:
The Main Functionint main() {
Yep, nothing new here. We're defining the main function, which runs when the program is run. Woohoo.
Piece 3: Introducing Flow Control, Part 1
while(true) {
Relax. This is pretty simple. The while-statement you see above is a type of loop. A loop is a block of code that executes multiple times, until a certain condition is reached. A while-statement does three things. First, it evaluates the expression in the parentheses to a boolean value. Second, if the expression evaluates to true, it makes the code between the following open-curly-brace and its matching close-curly-brace execute. Third, it repeats the first two steps until the expression evaluates to false.
Now take a close look at we have in the parentheses. Yes, that's right. The expression is simply 'true', which, of course, always evaluates to true. So, that means...
Stop that. Yes, the code between the braces will execute indefinitely, until the program is stopped. This is called an infinite loop. Most programming teachers will tell you that infinite loops are bad. I would agree for several situations. However, there are many, many situations where an infinite loop is
exactly what we need. Why do we want our code running forever? Well, we want to be able to accept input to the calculator as long as the user is willing to give input. And, as we'll see, the program won't actually run forever. There are ways to break out of an infinite loop.
Piece 4: Printing Stuff to Standard Output
cout << "Enter the function you wish to use (add, sub, mul, or div): ";
Just like in Lesson 1, we're printing a string (ahahaha! strings!) to standard output. However, this time, we're not outputting a newline (endl), because we want the input to be on the same line as the output.
Piece 5: Accepting User Input
string function;
cin >> function;
cout << endl;
int a, b;
cin >> a >> b;
First, we're declaring a string named function (don't get confused here). Nothing too fancy. Next, we tell cin (a stream like cout, but an input stream instead) to put what it's holding into function. Well, what exactly is it holding? User input, that's what. Whatever the user types into the program gets put into cin. When the user presses Enter, the program stops reading the input and puts the line (without the newline inserted by pressing Enter) into function. So, now, function contains what the user typed in. Then, we output a newline, because we want our next output to be on the next line after the current one. Next, we declare two ints, named a and b, and take values given by the user and store them in the two ints. Because values are given to a and b from cin in the same statement, the program takes two numbers separated by a space (or any number of spaces) as input, and correctly stores them in a and b. How can it do that?
Magic.
Piece 6: Introducing Flow Control, Part 2
if(function == "add") {
cout << a << " + " << b << " = " << a+b << endl;
}
else if(function == "sub") {
cout << a << " - " << b << " = " << a-b << endl;
}
else if(function == "mul") {
cout << a << " * " << b << " = " << a*b << endl;
}
else if(function == "div") {
cout << a << " / " << b << " = " << a/b << endl;
}
else {
cout << "That is not a valid option." << endl;
}
Here, we get introduced to what is known as conditional branching. Simply put, it means the program evaluates an expression to a boolean, and does something if it is true, or does something else if it is false. Conditional branching is a type of conditional statement, and is done using if-, else, and else-if-statements. An if-statement looks similar to a while-statement, and works similarly, too. The expression in parentheses is evaluated, and the code inside the curly braces is executed if the expression evaluates to true. Unlike a while-statement, an if-statement only executes the code once. An else-statement can follow an if-statement, and the code between the curly braces is executed if the expression in the if-statement evaluates to false. Finally, there are else-if-statements, which are really just else-statements that contain if-statements. It should be fairly easy to see what they do. Conditional statements and loops make up the portion of language features called flow control, because they allow you to control what your program does in different situations.
So, the code uses conditional branching to decide what to output. Next, let's look at the output itself. We see more compound statements, with the multiple data objects being put into cout. We saw earlier that, through compound statements, cin (as well as all other input streams) can make multiple data objects out of one source. Now, we see that cout (as well as all other output streams) can take multiple data objects and make one output. The reason it can do this is too complicated to explain fully at this point, but it deals with the data objects having certain properties that allow streams to do this. All primitive data types, as well as the string class, have these properties.
One thing we notice in the output code is the use of +, -, *, and / to calculate a sum, difference, product, and quotient, respectively. These are called operators, and these 4 are defined for use with all primitive data types, and can (in most cases) work with two different primitive data types. Operators will be a whole lesson in itself, because C++ provides some very neat things that you can do with operators.
Piece 7: The End
}
return 0;
}
First off, we have the close-curly-brace from the while-statement, way back in Piece 3. Next, we have our standard "return 0;". Finally, we have the close-curly-brace from the main function definition. Nothing much to say here.
Remember how I mentioned that you could break an infinite loop? Well, I'm about to teach you how. If you have something running in a console (Windows) or terminal (Linux/UNIX/Mac), you can use a key combination to kill the program, making it end immediately. In Windows, Linux, and UNIX, this key combination is Ctrl-C. For Mac, I'm not 100% sure (I don't own a Mac), but I believe it is Command-C.
Conclusion
We have make much progress in C++, but there is still much I have to teach you. I have left a lot of things unexplained (or said they were magic), but, as I said before, I will eventually go back and cover those details. Instead of considering what you don't know, let's look at what you do.
- You know how to use #include to add standard headers to your program.
- You know how to use the "using" directive to tell the compiler you want to use things defined in standard headers.
- You know how to define a main function.
- You know how to use cin and cout.
- You know about primitive integral data types and how to use them.
- You know a little bit about the string class, as far as using it for input and output.
- You know how to use while loops.
- You know how to use if-, else-, and else-if-statements for conditional branching.
Homework
The dreaded part of every lesson, homework! Don't worry, it's not too difficult. You have two assignments:
1. Play around with conditionals, loops, and primitive data types.
2. Learn why primitive data types have limitations on how large the ranges of values they can hold are.
I was feeling a bit silly, and I got a PM from a reader of this thread asking when I was going to do the next lesson in my tutorial, so the result is this silly-ish lesson. Again, if there's anything I didn't explain clearly enough and didn't attribute it to magic, ask me, and I'll explain it.