A Simple Program

The simplest C++ program (which shows good form and is technically complete) is:

    int main(void)
    {
        return 0;
    }

This program, when compiled and executed, will simply return to the operating system (OS). That's it, no more. Not terribly useful. But what can we learn from it? It has a function — called main. The int before the function's name indicates that, when it is done, the function will return an integer to whomever called it. (Or as mathematicians might say: "The result upon evaluating the function will be an integer value.") The ( ) after the function's name would normally surround a list of inputs (arguments in computer-speak). This function, however, requires no inputs from its caller and so the 'list' is simply the keyword void. (A keyword is a word that is special to the C++ language. The keywords in this program are int, void, and return.) This first line is altogether known as the function's head. As in biology, a head normally sits atop a body. This is represented by the { } portion of the program. The body of a function is where we describe to the compiler what we want that function to accomplish. In this case, the only task for the function to perform is to return a value of zero (0) to its caller. Wow, I guess it has a lot to it even though it doesn't do very much. Maybe it should go into politics...or photography...*shrug*

Here is a slightly more useful program (and the most well-known program among programmers):

    #include <iostream>

    using namespace std;

    int main(void)
    {
        cout << "Hello World!"
             << endl;
        return 0;
    }

These small changes actually bring much more power and even more to learn. From the top, the #include is known as a "pre-processor directive". (It's the # symbol that makes it a directive; include is the particular directive we are issuing.) This directive will tell the compiler to include the file iostream from the standard library. Although the C++ language has many useful features, some portions were not made part of the language itself but come as extras.

You might view C++ as having English as the language and then there are add-ons that detail chemistry, computer science, physics, engineering, medicine, carpentry, etc. Lots of specialized words used primarily in their particular discipline. That's kinda what the standard library is like. It collects together many specialized features that we can use to make our programming easier (like it is much simpler to say "computer" than to say "a box, often metal and/or plastic, containing a motherboard, RAM, a CPU, a hard drive, a CD-ROM, a power supply, ... and connected to a mouse, a keyboard, speakers, a monitor, a printer, ...").

One part of the standard library is the iostream library. (Here we hit a terminology problem. "Library" is used to describe each individual specialization as well as the entire collection of them. *sigh*) The iostream library defines a simple and portable (able to be used on many computer platforms) way to perform input and output. In particular, it defines the object cout. This is C++'s name for the (text) screen. It also defines the use of the << operator to insert items into cout. Finally, it defines the endl manipulator to end a line of output.

But what's that second line about? The "using namespace std;" line tells the compiler that you want to use symbols from the group of names called "std" — which is short for "standard. This is necessary because cout and endl are inside this group of names. Without the using statement, the compiler would feign ignorance when we later used those symbols. (There is another way around it, but it is icky, tricky, and tedious.)

Note on the cout statement that each of the two items to be printed is preceded by a << operator. The first one is the literal string "Hello World!". Anything placed inside double quotes (") is placed exactly — literally as indicated on the screen. The second item being printed is the endl symbol (which will end the line — moving the cursor to the beginning of the next line).

You can also note a few other things about this cout statement. The statement itself doesn't end until the semi-colon (;) after the endl. This single C++ statement (command) spans two physical lines of the program source code. This is perfectly legal. Although this statement could fit on a single line, I thought it would be instructive for you to see how to wrap a statement that did get too long for a single line. Note how the insertion operator (<<) on the continued line is a bit indented under the first line to show visibly that the previous line has been continued. (It also lines up with the insertion operator on the line above, but that just makes it look nicer.)

So, if we compile and run this program, what happens? It will print the sentence "Hello World!" (without the quotes) on the screen on a line by itself. Still not quite amazing, but certainly better than the first program which simply ended. This one actually does something before it ends. *smile*

But, literal strings and endls aren't all that cout can print. It can print any kind of literal data: integers, reals, and characters! Let's try it:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        cout << "Hello World!"
             << ' ' << "I'm " << 42
             << " years old.  I make " << '$' << 324.56
             << " each week." << endl;
        return 0;
    }

Here our poor imaginary person is old and truly poor. But let's see what values are printed and how. The strings are still there ("Hello World!", "I'm ", " years old. I make ", and " each week."), but we've added other items. Two of the outputs are in single quotes: ' ' and '$'. The compiler expects that multiple characters are placed in double quotes and that single characters are placed inside single quotes. The first is a single space character and the second is a dollar sign. (Note that when we say 'character' we are not referring to letters only. The term character means any individual character you can type at the keyboard: letters, punctuation, spacing -- even single digits.) Finally there are two numbers: the integer 42 and the real (fractional) number 324.56.

Compiling and running this program gives us very little more, however, than the "Hello World!" program. It still simply prints things out on the screen. *sigh*

A Slightly Better Program

One thing the computer is good at, though, is arithmetic. We can make a new program that does a few calculations before printing the answers. That might be better.

    #include <iostream>

    using namespace std;

    int main(void)
    {
        cout << "There will be " << (782*0.78)
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

Now we've got it multiplying! We multiply 782 by 0.78 and print the result. (The 0.78 multiplier comes from an assumed 22% reduction in the deer population.) We could get the same result by doing something like this:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        cout << "There will be " << (782 + 782 * -0.22)
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

A more complicated formula, but with the same results (mathematically speaking). So what math does the computer understand? Well, C++ includes the following mathematical operations (in order of reducing precedence):

    ( )
    - * /
    + -

Note that exponentiation (powers) is missing. (There is a ^ operator but it does not do powers.) C++ does, however, support a unary - operator for 'opposite', 'negation', or 'additive inverse'.

Still, this program leaves us feeling less than useful. In order to make it more useful, we'd need to let the person running the program (the user) enter their own deer population value. The iostream library is supposed to provide both input and output, right? Okay, but let's take this one step at a time. In order to input a value, we'll need a place to store it — a memory location. In C++ you must declare all memory locations before you can use them. Declaration of a memory location gives it a name and data type.

Variables

A data type? What's that?! Well, in math you had real numbers for the most part. Even integers were just a part (subset) of the real numbers.

But mathematics has infinite number sets (for the most part). Whereas, in the computer, things are a bit more restrictive. Because of the way the computer stores information all in binary (1s and 0s), we had to make decisions. Integers can be stored exactly, but the larger the integer, the more memory space it would need. Reals can have an infinite sequence of digits — not possible in the computer. Instead, we chop them down to a certain number of digits we are willing to keep precise (digits that have significant and real meaning). We also limit how large a real number can get by limiting the power of 10 that the real can have (like 103 is 1000 and 10-2 is 0.01; so by limiting how big that power can be, we limit the overall magnitude of the number).

So, what types of information are we dealing with here? We have the population of deer and the rate at which the population is 'growing' (dieing is just negative growth in math/science). The number of deer should probably be an integer (or do you count parts of a deer ... nah!). The growth rate should probably be a real (the example was 0.78, after all).

Complicating matters somewhat is that some computers look at the world in chunks of 16 bits (16 values which can each be 1 or 0; bit is short for binary digit) while others prefer 32-bit chunks. This mainly affects integers — in particular, the data type int is greatly affected (remember from the return of main?). If the computer that you are working on is a 32-bit computer, an int memory location will be 32 bits. This makes it able to hold values anywhere from -2147483648 to 2147483647. That's quite a range of possible values! On the other hand, if the computer you are working on is a 16-bit computer, an int memory location will be 16 bits. Now its range of possible values is only -32768 to 32767. That's a drastic reduction!

Now imagine that you are writing your programs on a 32-bit machine and your company is selling your programs to people using 16-bit machines. When you test your program, you can easily keep track of 45000 bolts, nails, etc. in a test inventory. When the customer tries to do it, though, your program tells him/her that there are -20535 bolts in the inventory! What went wrong? 45000 is too bit to fit in the -32768 to 32767 range so the computer did its best to stuff it in there. Unfortunately, only part of the information got in there and left it confused. Now your customer is not only out of stock but seemingly has oversold their stock!

To avoid these kinds of issues, we can use the data types short or long instead. A short is always [at least] 16 bits and a long is always at least 32 bits. (We don't have problems if a memory location gets bigger than we expected it to be.)

So, back to our program, the deer population is an integer quantity. How big will the population get? Will there be more than 32767 deer? Most forest preserves count their deer populations in the low thousands — very few breaking 10000. So, with that information, we decide that the population of deer should be stored in a short memory location.

The growth rate was a real number, though. We can't store that in a memory location that only supports integers. So we turn to the C++ data type double. double is a simplification of "double precision floating point". ("Floating point" is a reference to how the decimal point shifts back and forth as you multiply or divide by 10. It is often used in connection with scientific — or 'E' — notation. "Double precision" means that it keeps track of twice the number of precise digits. Twice what? Well the simplest real number type in C++ is float which can store 7 precise digits.) Although there are other real number types to choose from (float and long double), double is the default data type for real number math and is the best supported in current computer hardware.

Okay, so we've picked data types — now what? Now we need to declare the memory locations with a C++ declaration statement. In general, this is a data type keyword followed by a comma-separated list of names for the memory locations. As with all C++ statements, it is terminated by a semi-colon (;). Here is a new version of our program:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        short popul_deer;
        double growth_rate;
        popul_deer = 782;
        growth_rate = 0.78;
        popul_deer = growth_rate * popul_deer;
        cout << "There will be " << popul_deer
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

Now we have declared 2 memory locations to store information for us. Hmm...a place-holder for information...that sounds familiar... Oh yeah! Those are variables! But I thought variables were x and y and stuff..? Well, not in the real world. When you are on line 362 of a program it is hard to remember exactly what 'x' stood for. This is especially so when it is a program that was written before you joined the company and you are just trying to adjust it! (But it is also hard to recall such things a few weeks — even days — after you write a program when you've been writing other code since then.)

So in programming, we use variable names (identifiers) that have some meaning. Here "popul_deer" is fairly easily understood to be the population of deer. And likewise "growth_rate" is obviously the rate of growth. What's with the underscores (_)? Well, when you use more than one word to build up a variable name, we have to signify it somehow. The C++ language doesn't allow identifiers to contain spaces. So, without the underscore, we'd've had: populdeer and growthrate. It takes a second for you to pick out where the first word ends and the second one begins — and that's knowing that there are two words and not 3 or 4!

Luckily underscores are allowed in identifiers. The rules are:

    Identifiers may contain:  letters, digits, and/or underscores.
    Identifiers may start with:  letters or underscores (although we
                                 avoid the underscore here; it is
                                 traditionally used inside the
                                 standard library code — like inside
                                 iostream).
    Identifiers may be ~any~ length.
    Identifiers are case sensitive (A is different from a).

There is, though, another way to separate the words. Another fairly popular method is to capitalize the second (and any further) word: populDeer and growthRate. Depending on the font, this may or may not be distinct enough for the programmer to easily see.

So we have two variable declaration statements in our program now! What else is new? We also have 3 assignment statements. The first two store literal values into our two variables — the same values we'd used before. The third one looks a bit odd:

    popul_deer = growth_rate * popul_deer;

If this were math, we'd divide through by popul_deer and find that the growth_rate is 1. But that isn't how to read an assignment statement. What the compiler does with this is to evaluate the expression on the right side of the = sign (growth_rate * popul_deer). This will access the current values stored in the memory locations for the growth rate and deer population variables and multiply those values together. Then the result of the right hand expression is stored into the memory location indicated on the left side (popul_deer). Since the computer does this in two separate steps (access the old value of popul_deer and later store a new value there), there is no collision or problem.

Finally we have altered the cout statement to print the value of the popul_deer variable by simply placing the variable's identifier (preceded by an insertion operator) in the sequence of items to be printed.

Finally Input!

Well, now that we can create variables and manipulate them for calculation and output, we should discuss a little more about how C++ views input and output before we actually input values into our variable(s).

The input/output library is called "iostream". The i and o are (fairly) obviously input and output, but what's that 'stream' all about? Well, since C++ is an object-oriented language, it uses a lot of symbolism — treating portions of the program or computer as objects with their own properties and behaviors. In particular, the entire idea of input and output is being symbolized with a stream of data (kinda like stream of consciousness, without being conscious). Imagine the keyboard. You are typing away at it. Where do those keystrokes go? They travel up a wire (or an infrared beam) to the computer and then into whatever program you are currently running. Each keystroke makes its way into the program independently (albeit in order) and the program then translates the individual characters into meaningful information for processing. Now imagine the screen. As the program produces output, it is sent down a wire to the monitor to be displayed. Instead of these wires, Bjarne Strousstrup imagined the data floating down a little river or stream. Sadly, I'll attempt to draw it:

    +============+
    |            |~
    |   Screen   |  ~
    |            |    ~          +------------+
    |            |~     ~        |            |
    +============+  ~     ~~~~~~~|            |
                      ~          |     P      |
                        ~~~~~~~~~|     r      |
                                 |     o      |
                                 |     g      |
                                 |     r      |
                                ~|     a      |
                              ~  |     m      |
    +====================+  ~   ~|            |
    |                    |~   ~  |            |
    |      Keyboard      |  ~    +------------+
    |                    |~
    +====================+

Now, since the information is flowing from the program to the screen, it was decided that the << operator looked like an arrow head that pointed in that direction and so it was used to indicate the direction that information was flowing along the output stream. Likewise, since information is flowing from the keyboard to the program, the >> operator was used for input to indicate that information was flowing from the keyboard into the program's variables.

Since traditionally the screen and keyboard taken together as a unit were called the 'console', we named the output stream C-OUT (as in Console OUTput). Anyone wanna guess what the input stream is called? Right! C-IN (or cin if you are actually writing a program).

In addition to all of this, it seemed silly for the information to just be floating in the water like that — so we gave it a boat to ride on. Both streams (cout and cin) have their own boat (although it is actually called a buffer). The boat (buffer) on cout can hold approximately 4096 characters (this number is system dependent, though). When all of this space is filled, cout will print it on the screen. Let's consider this: a whole text screen is 80 columns by 25 rows or 2000 characters. So the buffer holds a little over 2 screen fulls of information. When will it reach that? Not any time soon. Especially since most output doesn't reach across the entire screen — filling only partial lines. So, cout will also empty its buffer in three other situations:

    -- when buffer is full
    -- when the program ends
    -- when an endl is inserted into the stream
    -- when cin is about to read what the user is typing

Both of the first two happen fairly rarely. (Not that programs rarely end, but that most good programmers have forced cout to empty its buffer before the program ends.) The third happens a decent amount (although we'll find other ways to end a line besides endl and its frequency will then drop).

What's that last one about? What does input have to do with output? Well, before the user can type information into your program, they must know what to type. Your program, therefore, should print a 'prompt' (prompting them for information) which indicates what (and sometimes how) they are to type. If your prompt didn't drop to a new line via an endl (or happen to be the last thing to fill the buffer), the user wouldn't see it and yet your program would stop while cin waited for them to type their answer. It would look like your program had 'hung' (died without returning control to the OS). Not good. That's why whenever cin is about to read from the user, cout empties its buffer — so that any waiting prompts will be displayed before the user is expected to type.

So, how do they type? cin has a few rules about how information is expected to be portrayed. First, all individual items of information are to be separated by some form of spacing (Spacebar, Tab, Enter, etc.). Second, numbers can have an optional sign immediately in front of them (-4, +5.6). After that, integers will consist of only the digits (0-9) in any sequence. Real numbers, however, can have digits up front or not. They can have a decimal point. After the decimal point can come another sequence of digits (no sign on this one, though *grin*). Then you can have an e or E to indicate scientific notation. If present, that should be followed by a (possibly) signed exponent (which is another sequence of digits). Whew! Let's have a few examples:

    integers                  real numbers
   --------------+-------------------------------------
      4          |             4
      +4         |             +4
      -4         |             -4
      -400       |             -4e+2
      40000      |             40000000e-3
                 |             -0.42
                 |             -.42
                 |             -4.
                 |             -4.0
                 |             -4.0e3

There's a lot of stuff on the keyboard that isn't allowed in those numeric data types. What happens if the user types them? Well, if cin is trying to read a number, it will get upset, leave the offensive character in the buffer, and refuse to do anything else until the program ends (when it will clean up the keyboard for the OS to use). But, I said 'if' it were reading numbers. What else could it be reading? Well, there is another data type that can store any individual character the user can type at her/his keyboard. It is called, oddly enough, char. We've already seen literals of this type (recall the ' ' and '$' from above). So, if we are expecting them to type non-numeric characters, we can read those into a char type variable.

With all that in place, it is time for the long-awaited update to our population program:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        short popul_deer;
        double growth_rate;
        growth_rate = 0.78;
        cout << "How many deer are there this year?  ";
        cin >> popul_deer;
        popul_deer = growth_rate * popul_deer;
        cout << "There will be " << popul_deer
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

Cool. Oooo. Ooohhhhh. Aaahhhh. Sorry...just got carried away. *grin*

But seriously, now every time the user runs the program, they can enter a different value for the deer population and still get the correct 22% drop reported back! That's a lot more power in our program.

Next let's consider the growth rate issue. So far, we've had a constant (unchanging) rate of 0.78 (22% decrease). What happens, if we had an accident as we coded this program such as:

        popul_deer = growth_rate = popul_deer;

Oddly enough, this isn't an error to the compiler. It simply thinks you are assigning the deer population to the growth rate and then assigning that value into the deer population again. (You evaluate them from right to left.) It wouldn't produce much in the way of results...but at least it is fairly quick to find...hopefully.

How can we get the compiler to help us find such problems? We can tell the compiler that growth_rate isn't a variable but a constant! A variable can change (vary). A constant can't. So we change the declaration of the growth_rate memory location to look like this:

        const double growth_rate = 0.78;

Now when the compiler sees something that would change the growth_rate (like the accidental assignment above), it will generate an error so we can really easily see it.

But, is the growth rate actually always going to be a 22% decrease? Not likely. The deer wouldn't last too long at that rate (no pun intended), would they? So, we really should leave the growth rate a variable and allow the user to input their own value for it:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        short popul_deer;
        double growth_rate;
        cout << "By what multiplicative rate is the deer population "
                "changing?  ";
        cin >> growth_rate;
        cout << "How many deer are there this year?  ";
        cin >> popul_deer;
        popul_deer = growth_rate * popul_deer;
        cout << "There will be " << popul_deer
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

(Note how the string literal "changing? " isn't preceded by an insertion operator. This is a special case when two string literals are used in sequence, the compiler will remove the intervening spacing and connect them together automatically. This can be handy when we are breaking a string that wouldn't fit on a single line. Note also that the string must begin and end on the same physical line of the file. That's why we ended the first string after "...tion " and then began the next one on the next line.)

Better, but still we have issues. How many of our users (park rangers, freshman biology students, etc.) will know what a 'multiplicative rate' is? (Did you know before I explained it above?) Not many. So we might want to allow them to enter a positive or negative percent value and convert it inside the program:

        cout << "What was the percent change in the deer population?  ";
        cin >> growth_rate;
        growth_rate = 1 + growth_rate/100;

Much nicer. And if it is a 22% drop, the user can still enter -22 and the assignment gets:

    -22/100 --> -0.22
    1 + -0.22 --> 0.78

Um...but if it is a percent, how many people will enter '-22' and how many will enter '-22%'? Hmm... Sadly, I'm betting on the latter. Let's see what that will do to our program.

The program begins and the user sees:

$ population.out
What was the percent change in the deer population?  _

They type their response and hit Enter:

$ population.out
What was the percent change in the deer population?  -22%
_

Now cin's buffer looks like this:

-22%\n

Okay...hey! What's that \n thing?! That's how C++ represents the Enter key. It is a special character. The \ is known as the escape character and so doesn't really exist except to make the next character special. We'll deal more with that later, but for now, just know that the \ and n together represent the Enter keystroke.

So, it reads for a double (growth_rate):

-22%\n              negative
-22%\n              negative two
-22%\n              negative twenty-two
-22%\n              not numeric — done:  -22.0

And we get the -22 just fine, calculate our 0.78, and then we get to the deer population:

$ population.out
What was the percent change in the deer population?  -22%
How many deer are there this year?  _

At this point, cin is told to read a short integer (popul_deer). It looks to the buffer and sees (effectively):

%\n

The '%' isn't numeric right away. But it hasn't translated anything yet! It gets very upset. It thinks it has failed you. That's when it stops working. It doesn't store anything into popul_deer — and so it has whatever random bits happened to be in that memory location when the program began executing. We then calculate the new population — using the random bits as if they were our current population. We print this surprising answer and are done. *ick*

To fix this, since we anticipate the user typing in a percent sign, we can add a char variable to hold this symbol (remember, a char can hold any single keystroke):

    #include <iostream>

    using namespace std;

    int main(void)
    {
        char pcent;
        short popul_deer;
        double growth_rate;
        cout << "What was the percent change in the deer population?  ";
        cin >> growth_rate >> pcent;
        growth_rate = 1 + growth_rate/100;
        cout << "How many deer are there this year?  ";
        cin >> popul_deer;
        popul_deer = growth_rate * popul_deer;
        cout << "There will be " << popul_deer
             << " deer next season due to harsh winter conditions."
             << endl;
        return 0;
    }

Now when we (recompile and) run the program, it will work just fine.

For more cool information on input see the basics page and the character mixing page.

Filling in Some Cracks with Data Types

First let's fill in some details about the types we've learned:

Type NameMinimumMaximumPrecision
double-1e+308+1e+30815
short-3276832767N/A
long-2 billion2 billionN/A
char'\0'ASCIIN/A

Only double has a precision because it is the only one which is imprecise. The exact figures for long are -(2^31) and (2^31)-1. char data are stored with an encoding scheme known as ASCII (the American Standard Code for Information Interchange). The first of these codes is represented by the escape (special character) \0. It is indeed special as it is the only character that cannot be typed at the keyboard. We'll use it to good effect later in the semester.

In addition to the above types for numbers and characters, there is another data type used for performing logic operations (and, not, or, etc.). Its name is bool. I know: it is a strange name, but listen to the story...

George Boole invented an algebra that dealt with true's and false's. We named it boolean algebra after him. Then, also in deference to Mr. Boole's contribution, C++ named their logical data type bool (a shortening of 'boolean').

As with the other non-double types, bool is stored exactly. In fact, it only has two possible values: false and true. Note that the values are not no and yes, off and on, 0 and 1, non and oui, or any other pair. They are the words false and true. We'll actually get down to using these later in the semester when we discuss advanced functions and flow control.

Finally, we mentioned escape sequences like \n and \0 and we'd said there were others. First I'd like to reinforce that these special characters are only allowed inside string or char literals. Here is a table of the special characters and their meanings:

EscapeMeaning
\n a new-line
(a combination of a carriage return and a line feed)
\ra carriage return
\ta (horizontal) tab
\aan alarm (beep) sound
\ba backspace
\0 the only ASCII value you cannot type at the keyboard

Try them out by inserting them in the string in your HelloWorld program. They're fun!

Filling in Some Cracks with Output

From the discussion(s) above, you may infer that their are subtle differences between using an endl and using the escape \n. First, endl is inserted into the stream on its own whereas \n needs to be inside a string or character literal. Second, endl forces the buffer to empty whereas \n will just sit in the buffer and wait for one of the other emptying conditions to happen. Finally, \n is less typing (if you are ending the output with a string — otherwise it is the same amount of typing: '\n' vs. endl).

Filling in Some Cracks with Arithmetic

Casting Call! Casting Call! Auditions for *NEW* Show!

If you've taken the population program and tried to compile and run it (any of them since we added variables), you'll notice that there are a warning or two. It is upset with the line that calculates the new population of deer:

        popul_deer = growth_rate * popul_deer;

What it is trying to say is that you are trying to store a double value into a short memory location. It wants you to understand that when this happens any fractional portion of the value will be lost — truncated — chopped off!

Although warnings allow your program to compile and later execute, they are generally a good thing to fix. To fix this one, we just need to tell it that we understand we are truncating and that we are okay with that. To do this, we'll need to change the product to a short integer — but not really, just for the duration of the assignment operation. The process of temporarily altering the data type of a value is called type-casting. In C++ there are at least 3 ways to do this: C style, old C++ style, and new C++ style. Here is old C++ style:

        popul_deer = short(growth_rate * popul_deer);

It doesn't look too bad until you realize that short isn't a function but a data type. Also it won't work for data types whose names consist of multiple words (such as long double or unsigned long). We are trying to leave it behind, but you still need to know of its existence.

Here is new C++ style:

        popul_deer = static_cast<short>(growth_rate * popul_deer);

Wow! That's a mouthful! This works for all types. Looks like a function call because it kinda is. But it is terribly long! Sadly, that was on purpose. The design was to make you think about type-casting before you took it on. *shrug*

Finally, there is the older C style (which we support because C++ extended C):

        popul_deer = (short)(growth_rate * popul_deer);

Small. To the point. Little extra verbiage. Works for all data types. Looks a little like mathematical multiplication by position (xy meaning x*y for instance), but that isn't allowed in C++ so it isn't.

Sadly, it does things that should not be done under normal circumstances. The details are a little too gory for this level of course (or at least at this stage of the semester), so I'll forgo those. But trust me when I say that static_cast is the way to go.

Equal-ish...yet Not Separate..?

Another thing that you'll notice (eventually) is that division doesn't quite work the same for integers as it does for real numbers — in the computer, that is. For instance, when dividing 6 by 4 you might expect to receive 1.5 as an answer. No. You'll get only 1 because the computer, seeing integers enter the divider will send an integer out. The half is still there, but we need to do something else to get at it. What you do depends on how you want the half returned. Hunh? That is, do you want 0.5 or do you want 2 remaining (of 4). To get the 0.5 you need simply add a .0 on one of your divisors or (if you have no literals in the division) you can use a type-cast to double. If you want to know that there were 2 left over after the 4 went into 6 once, you need what is known to 4th graders as remainder and to more mature mathematicians as the modulo operation (also see the modulo operator entry; and btw, the 'divisor' in a modulo operation is called the modulus; and, although I'd rather not start a Latin grammar fight, does anyone know if more than one modulus would be moduli or moduluses? *shrug*). To make matters worse, the operator symbol in C++ is % — but it has nothing to do with percentages!!! (It was chosen by our ancestor language, C and has been passed down to many other siblings, second cousins, step children, etc. — csh, Perl, Java, javascript, ...)

Weird, eh? Let's use it before you toss it aside. Maybe it's useful...

Unit Conversion

Whenever you are converting units (especially in the English system of units), modulo comes in handy. For example, given that some item is 463 inches long, how many yards, feet, and inches does that equal?

    463 / (12*3) = 12
    463 % (12*3) = 31
     31 / 12     = 2
     31 % 12     = 7

So we see that 463 inches is equal to 12 yards, 2 feet, and 7 inches. Where did the divisors come from? 12 is the number of inches in a foot and 12*3=36 is the number of inches in a yard (because there are 3 feet in a yard). More practically, let's look at 63 inches 'graphically':

    63 inches:
        |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

    count whole yards:   63/36 = 1
        ||||||||||||||||||||||||||||||||||||   |||||||||||||||||||||||||||

    there are 27 left:    63%36 = 27
        |||||||||||||||||||||||||||

    count whole feet:    27/12 = 2
        ||||||||||||||||||||||||   |||

    there are 3 inches left: 27%12 = 3
        |||

The division tells you how many whole of something was present. The modulo tells you how many of the smaller things were left after the larger ones where extracted.

BTW, in code, this would look something like this:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        long inches, yards;
        short feet, inches_left;

        cout << "How many (whole) inches do you have?  ";
        cin >> inches;

        yards = inches / (12*3);
        feet = inches % (12*3) / 12;
        inches_left = inches % (12*3) % 12;

        cout << inches << " inches is equal to:\n\t"
             << yards << " yards, " << feet
             << " feet, and " << inches_left << " inches.\n";

        return 0;
    }

Hmm...don't all those 12's and (12*3)'s make things look ugly. And, if we didn't know the English system of units as well as we did, whose to say we'd even know what all of them were for!? In fact, we've stumbled on what programmers often term "magic numbers". They are literal numbers in code (usually calculations) that seem to produce the correct results, but it isn't clear why they are working. This lack of clarity can lead to programmer confusion — and the last thing we need is a confused programmer! To avoid magic numbers, we merely create a constant into which we place the magic number. This solves the cluttered look of literals and the confusion in one swoop: by giving our constant a clear and meaningful identifier, anyone will be able to know what's going on.

(Not all literal numbers are magic, of course. Sometimes it is clear what is going on just from the context. In the calculation '(a + b) / 2', for instance, it is clear that the 2 is being used to take an average of the numbers a and b. However, in general, any unit conversion factors, science or math constants, and the like should be assumed magic numbers no matter how obvious they seem at the time!)

So, let's clean up our inch conversion program:

    #include <iostream>

    using namespace std;

    int main(void)
    {
        const short inches_per_foot = 12,
                    feet_per_yard = 3,
                    inches_per_yard = inches_per_foot * feet_per_yard;

        long inches, yards;
        short feet, inches_left;

        cout << "How many (whole) inches do you have?  ";
        cin >> inches;

        yards = inches / inches_per_yard;
        feet = inches % inches_per_yard / inches_per_foot;
        inches_left = inches % inches_per_yard % inches_per_foot;

        cout << inches << " inches is equal to:\n\t"
             << yards << " yards, " << feet
             << " feet, and " << inches_left << " inches.\n";

        return 0;
    }

Now we have clearly named constants for our conversion factors and our calculations even read more clearly. Note, also, how we've let the compiler build the final constant for us. This saves us troubles caused by typographic errors. The 12 and 3 are easy to check, but we could go wrong at any of several steps (typing them into the calculator, reading the result, typing the result into our code, etc.) with the 36.

But that does, I'll admit, seem trivial. Let's look at another set of constants for time unit conversions:

    const short seconds_per_minute = 60,
                minutes_per_hour = 60,
                seconds_per_hour = seconds_per_minute * minutes_per_hour;

Now here's some entertainment! I've witnessed countless students enter 360 by hand instead of the correct 3600. And they don't even notice that their answers are wrong! (The sad thing is that most students do run their programs — they have to for full credit, after all — but they don't pay attention to the answers that come out. Make sure you always check your answers to ensure that they are correct!) And, as if that weren't enough, try adding the next level:

    const short hours_per_day = 24;
    const long seconds_per_day = static_cast<long>(seconds_per_hour) * hours_per_day;

Here we need a little savvy to realize that this product is going to overflow a short integer (think 6*6*2=72, add the 3 zeros on the end: 72000 — oops!). The cast is sadly necessary since the compiler will do purely short integer arithmetic unless one of them is turned (temporarily) into a long integer.

One last look at the style of these constants before we return to the wonders of modulo:

    const short inches_per_foot = 12,
                inches_per_yard = inches_per_foot * 3;

    const short seconds_per_minute = 60,
                seconds_per_hour = seconds_per_minute * 60;
    const long seconds_per_day = seconds_per_hour * 24L;

In this version, we don't use the intermediate constants to name all the literals. We are using literals where it would seem clear from context what is going on. We could even add comments to make sure it was clear. But, even so, we allow the compiler to build up the higher-level constants and just enter the simple parts ourselves. (Note the 'L' on the 24 to make this a long integer literal. Without it, the 24 would be a plain integer and the result may or may not work — depends on if it is a 16- or 32-bit machine.)

Now, back to our regularly scheduled modulo show:

And it works on any units: inches, centimeters, seconds, pennies, etc. (So physical, time, money, etc.)

Digit Extraction

But that's not all! You can also use modulo to extract digits or groups of digits from a larger number. Let's take a phone number for instance. A phone number is a 10 digit quantity taken without its normal separators. Ignoring for the moment that we can't store all the phone numbers (even an unsigned long only goes to 4 billion), we read in the number as a single value:

    unsigned long phone_number;

    cout << "What's your phone number (no separators):  ";
    cin >> phone_number;

Next we extract the area code (the first three digits):

    short area_code;

    area_code = phone_number / 10000000;

By dividing by 1e7 we shift the decimal 7 places over. But since this is integer arithmetic, we truncate the fraction and get just the whole part.

Now for the exchange (the middle 3 digits):

    short exchange;

    exchange = phone_number % 10000000 / 10000;

Now, the remainder by 1e7 gives us the last 7 digits of the number — the fraction the division threw away! Then we divide by 1e4 to shift the decimal and truncate the last four digits away.

Finally for the line (the last four digits):

    short line;

    line = phone_number % 10000;

Notice how we simply snatch the remainder from 1e4 — not even caring how many digits there were above that.

(I kept saying the numbers in 'e' notation in the text above, but the code had them as integers. They have to be integers for modulo. The compiler figures if you already have decimal places, it can give you a fractional answer and so modulo isn't allowed for floating point arithmetic.)

There are many other applications of modulo. We'll see one during our discussion of random numbers and more when we reach repetition and containers.