In the first chapter, the book refers to C++ as a “high level language.” What, exactly, does that mean? Let’s go through a bit of computer history to find out.
In the early days of microcomputers, you had to enter your programs by using switches on the front panel to enter the ones and zeros corresponding to the machine instructions that you wanted to perform. This is called programming in machine language Say you wanted to add the number at memory location 20 to the number at memory location 21, and put the result at memory location 22. Here’s what it looks like for the 6502 microprocessor:
1010 1101 0001 0100 0000 0000 0110 1101 0001 0101 0000 0000 1000 1101 0001 0110 0000 0000
You can see the problem here–it all looks alike, and without a reference manual, it’s next to impossible to tell what’s going on. Machine language is a low-level language because it is as close to the raw hardware as you can get.
Programmers soon got tired of writing ones and zeros, and some very clever programmers decided to assign a mnemonic to each set of ones and zeros that corresponded to a machine instruction. You could then write your program using these easier-to-read mnemonics, and a program called an assembler would take those mnemonics and translate them into the ones and zeros for you. Here’s the same program in assembler:
LDA 20 ADC 21 STA 22
That’s better, but not by much. The mnemonics are a little bit
unusual: LDA means “load accumulator,”
ADC means “add with carry,” and STA
means “store accumulator.” Two problems still remain.
In assembler and
machine language, you are responsible for figuring out where to put
everything in memory. Also, the program is good only for one kind of
platform, since different microprocessors have different combinations
of ones and zeros to stand for “add” or ”store.”
In a high level language, you write in a notation that’s familiar to you, and a program called a compiler takes that notation and translates it into the ones and zeros that the CPU understands. Here’s a C++ statement to do the addition:
result = firstNumber + secondNumber;
All the problems are solved now. You don’t have to worry about ones and zeros, or where things go in memory–the compiler figures all of that out for you. Since C++ compilers are available on almost every platform, you can write your program once and use it on many different types of computers.
Back in the bad old days, everyone wrote all their own code. If you wanted to print something, you needed to write code to drive the printer mechanism. So did the next guy who wanted to print output. If you wanted to calculate square roots, you wrote the code for it, and so did the next guy.
This clearly was not a good use of people’s time, so, again, some very clever programmers got together and wrote libraries of commonly used tasks like reading from the keyboard, writing to the screen or printer, and calculating heavy math stuff. They then wrote a program called a linker which combined the libraries with your code. This, again, made everyone’s life easier.
So that brings us to where we are today. You use the text editor of your choice to write the source code in C++. You then run your code through a compiler, which produces machine-readable ones and zeros called an object file. The code then goes to the linker, which combines the object file with the libraries you need, producing an executable program.
In this class, we will be using an integrated development environment called Dev-C++. It has the editor, compiler, and linker all in one easy-to-use package so that you don’t need to have separate steps.
Part of the software development cycle is getting rid of errors. As the book mentions, there are three types of errors.
These are also called compile errors. These are the equivalent of spelling, punctuation, and grammar errors in English. You have to get rid of these errors before you can get your program to run, just as you would have to correct the following sentence if you expected anyone to understand you.
Givve I a cookies?
These happen when you refer incorrectly to some task in a library. For example,
if you refer to the sqrt (square root) function as
sqroot, the
linker will complain that it can’t find anything by that name.
It’s like telling someone:
Talk to Moishe Pipik.
That’s grammatically correct, but it refers to a non-existent person.
These are the hardest to find. Run-time errors happen when you say something that doesn’t do what you want. For example:
Go west from San Jose to get to Los Angeles.
This sentence is the equivalent of a run-time error. It’s not a syntax error–the grammar, spelling, and punctuation are fine. It’s not a link error–both San Jose and Los Angeles exist. It’s a run-time error, because if you follow the instructions, you definitely do not arrive in Los Angeles.
Sometimes you will write code that is not an error, but may have some unintended consequence. For example, if you assign a floating point number to an integer, the compiler will warn you about it, because you will lose the fractional part of the floating point number. Errors are like having your car’s transmission fall out–you have to fix those. Warnings are like the warning lights on the dashboard. You can ignore them, but you do so at your peril. In this class, your programs must compile without any warning messages.
On page 6, the book notes that judicious use of whitespace helps make
programs clearer. If you look at the program on page 5, you will see that
the lines between the braces { and } are
indented. This is not just a good idea; in this class, it is the law.
Every time you open a new { you must indent one level,
and every time you close a } you must un-indent one level.
This seems like a waste of time for small programs, but when your programs
get to any level of complexity, you will be glad you are indenting properly.
Your eye will guide you to blocks of code, and it will be easy to see how
your program is structured. You will also be glad that you don’t lose
points when I grade your program.
The explanation of std::endl doesn’t tell you what
endl stands for–end of line. That’s
a letter ell, not a digit one.
main( )
On page 8, the book should really say that “[r]eturning 0 from
main( ) is a way to indicate that the program ended
without a problem that the operating system
needs to take care of.” Your program may not have done
what you wanted it to, but that is your problem, not
Windows’. That’s why you always return zero–to tell the
operating system that it doesn’t need to do any special handling
after your program finishes.
using DeclarationsThe technique shown in the middle of page 10:
using std::cout; using std::endl;
is the one that we will use in this class because of the advantages described in the book: it explicitly spells out what parts of the library we will use, and it doesn’t bring in elements that we won’t be using. As the book says on page 11, “you’ll probably receive coding standards created by the person in charge.” Consider this your receipt <grin/>.
What in the world is this floating point business? It’s time for a bit of history. In early programming languages such as COBOL, which was designed for business applications, you either had whole numbers (integers) or numbers with a fixed number of places after the decimal point. Thus, memory locations holding monetary values would be defined to have a fixed (decimal) point of two places.
The scientists of the world didn’t like this approach very much. They wanted as much precision as they could get, and the number of places to the right of the decimal would change, or float during the process of a calculation. Thus the term floating point. This distinction between fixed and floating point isn’t important to us in C++, but the name remains. Just consider any number with a fractional part to be a floating point number.
On page 16, you are introduced to the double type of variable.
This name comes from the words “double precision.” The
history: in the early days, floating point variables took up four bytes.
They could only hold about seven digits accuracy. The scientists, again,
complained. The designers of programming languages then introduced
variables that took up eight bytes of storage, giving you double the
precision (accuracy) of a regular floating point variable. That’s
where the double type comes from. We will always use
double in this class. Yes, it takes up a bit more memory
and processing time for
each variable, but what’s an extra few bytes when you have 512
megabytes of memory, or a few
nanoseconds when you have a 1.6 Gigahertz processor?
This is my favorite arithmetic operator in the whole world. You may think
it’s pretty useless, but it pops up in all sorts of places. For
example, to convert 173 minutes to hours and minutes, you divide by 60
to get 2 hours. Then calculate
173 % 60, giving you the remainder of 53 minutes.
THus, 173 minutes is 2 hours and 53 minutes. Similarly, you can use
% to convert inches to feet and inches, or units to dozens
and units.
The quick guide to order of operations is a modification of something I learned in algebra class to help memorize their precedence:
| Please | ( ) parentheses |
| Meet Dear Maiden | * / % |
| Aunt Sally | + - |
Multiplication, division, and modulus are all at the same level of precedence. Addition and subtraction are at the same level of precedence.
On page 17, the book gives this example:
short lives, aliensKilled;
There are three things to change here. In order from least to most important, they are:
short in this class. Instead, we will always use
int.Our revised declaration will look like this:
int lives = 0; int aliensKilled = 0;
Important: Even though the book says
on page 17 that you don’t have to declare all of your variables
in one place, and that the author defines new variables just before
using them, we will always put all our variable declarations
in one place, right after the beginning {. This makes it
much easier to get a grasp of what variables a program uses, rather than
having to search for declarations scattered throughout a program.
Similarly, the programming standards for this class will use mixed upper and lower case for multi-word variable names; thus:
int cardsDealt = 0;We won’t be defining new names for existing types as shown at the bottom of page 20.
Here’s how the assignment operator = works:
=.=.Consider this code:
int score = 0; score = 5 * 7; score = score + 1;
The first statement,
int score = 0;
declares variable score and
assigns it a value. The = works exactly as described above.
The right hand side is evaluated, and it works out to, amazingly,
zero. The zero goes into the variable named score.
The second
statement, score = 5 * 7; will
pull out a piece of scratch paper and completely evaluate
the expression 5 * 7. The result, 35,
will go into the variable score, replacing the 0
that used to be there.
The third statement,
score = score + 1;
is illegal in algebra, but this isn’t
algebra; it’s C++. Let’s follow the rules:
score right now? 35, as you see in
the preceding illlustration. Add one to it, yielding
36.score, replacing the old value.
The key point to take away from this section is that adding and
subtracting 1 from a variable is so common that there is are
special operators for those tasks. You use ++ to
increment a variable, and -- to decrement a variable.
| These... | ...are effectively the same as |
|---|---|
score++; |
score = score + 1; |
lives--; |
lives = lives - 1; |
The tricky part of ++ and -- comes when they
are in combination with other operations. These two statements from the book
have two very different effects. The first one does the addition to
lives before the assignment takes place. The second
one does the addition to lives after the assignment
takes place.
bonus = ++lives * 10; bonus = lives++ * 10;
If you aren’t sure how it works, just do it as two separate statements in the order you want.
| This... | ...can be written as |
|---|---|
bonus = ++lives * 10; |
lives = lives + 1; |
bonus = lives++ * 10; |
bonus = lives * 10; |
The programming standards for this course say that names of constants must be all uppercase. As in the book’s example, if a constant name has more than one word in it, separate the words with an underscore. Thus:
const int ALIEN_POINTS = 150; const int MAXIMUM_SCORE = 32000; const double NORMAL_TEMPERATURE = 98.6;