Lecture 1: Introduction  

Organisation of a computer

Any computer consists of the following components:

CPU
Central Processing Unit. Controls the operation of the entire system, performs arithmetic and logic operations, and stores temporarily instructions and data. It contains a 'memory unit', a 'control unit', and a 'arithmetic-logic unit'.
RAM
Random Access Memory. Fast, volatile memory to store information as long as the computer is turned on. Volatile memory, in this case, means that the memory contents are erased when the computer is turned off.
Secondary Memory
Provides long-term, non-volatile storage of information that persists even when the computer is turned off (floppy disk, hard disk, CD ROM)
Input/output devices
Used to interact with a person or other devices (screen, keyboard, mouse, modem, printer)

These pieces interact with each other, all under the control of the CPU. In this class we will learn ways to guide the CPU of a computer to solve certain tasks for us.

The memory of a computer is comprised of a sequence of 'two-state' devices, i.e. each device can contain one of two states, usually called 0 or 1. That means that everything the computer stores must be stored as sequences of 0's and 1's. That's of course inconvenient, and several 'translations mechanisms' translate between 'machine language' and more convenient languages and numbers. One such translation mechanism is provided by the C++ programming language (other programming languages are Fortran, Pascal, C, Java, APL, Scheme, Lisp, Prolog, ADA, and many others).

About C++

C++ is a high-level, general purpose, object-oriented programming language. It can be used to get the computer to do virtually anything (given the limitations of the particular system). But, on the other hand, when  executing a program that you wrote the computer only does what you have programmed it to do, no less, but also no more. If you forget anything, or the output does not look pretty, or the results of computations are incorrect, there's nobody to blame but yourself.

One basic problem in creating your own program is the "language barrier": the computer understands (long) sequences of 0's and 1's, humans only understand a natural language such as English. Therefore, there is a translation mechanism involved when you try to tell the computer what you want it to do:

Source code: The source code is a text document that contains statements written according to the rules of the programming language (in our case C++). It is not English, but good programming code should - almost - be understandble as a plain English document. Source code is written by humans (although there are expert computer systems that can also produce source code), and is understandable by humans, but not directly by the computer.  You can create a source code file with virtually any text editor or word processor, if necessary.
Object code: A sequence of 0's and 1's that the computer can, in principle, understand (machine code). A program called the compiler is used to translate the source code into object code. The object code, by itself, can not yet execute on the computer because several pieces may be missing.  The compile only translates your source code, and there maybe other code necessary to create a complete, working program. The process of converting the source code into machine code is called compiling.
Executable code: A sequence of 0's and 1's, consisting of your object code plus any other modules (in object code) that may be necessary for the computer to execute your program. This is the end result of creating a finished program, and the computer can execute it. The process of combining your object code with any other necessary object code is called linking, and the program that combines the various object code files is called linker.

A programming language, such as C++, merely provides a vocabulary and a grammer to create a source code file that can be understood and translated correctly by the compiler and linker.

 A Simple Sample Program

Here is a simple program (in source code), written according to the C++  standard. There are many details that we need to explain, so don't worry if many things are not quite clear immediately; we'll explain the the details of C++ later.

Task/Goal: Create a program that will compute the volume of a sphere, given its radius.

In most cases when we need to solve a particular programming problem, we will proceed in different stages. Each stage will bring us closer to solving the desired task.


Stage 0: This stage is the basic outline for every C++ program. In other words, every C++ program you  create will include at least the following lines:

#include <iostream.h>

int main(void)
{
   some stuff here
   return 0;
}

Of course, the phrase some stuff here must be replaced by suitable C++ compliant statements. We will discuss later what exactly these lines mean; for now, just remember that every C++ program will include them.


Stage 1: Next, we will break up our task into several sub-tasks. This is actually the most important part of creating a program: defining the sub-tasks so that each is responsible for solving one small, well-defined piece of the total task. If this step is performed carefully, the rest is usually easy. In our case, there are three different subtasks:

asking the user to enter a value for the radius of the sphere
computing the volume of the sphere according to the formula V = 4/3 * Pi * r^3
displaying the answer on the screen

At this stage, we will not worry about how to actually solve these subtasks; we will merely state what they are:

#include <iostream.h>

int main(void)
{
   // ask user for the value of the radius
   // compute the volume of the sphere (V = 4/3 * Pi * r^3)
   // display the answer on the screen
   return 0;
}

Note that we have used "plain english" to describe our subtasks, prefaced by a double-slash //. That is called a comment: a comment consists of one or more lines of plain english text, describing what your program is supposed to accomplish at that particular point. Comments are prefaced by a double-slash //. The compiler will simply ignore everything after a double-slash until the end of the line. Therefore, the compile would interpret the stage-0 and stage-1 programs as being the same.


Stage 2: Now that we have broken down our task into various subtasks, we can go about solving each subtask separately. Here is the code, with the explanations later:

#include <iostream.h>

int main(void)
{
   // ask user for the value of the radius
   double r;
   cin >> r;
   // compute the volume of the sphere (V = 4/3 * Pi * r^3)
   double V = 4.0 / 3.0 * Pi * r^3;   
   // display the answer on the screen
   cout << V;
   return 0;
}

These - perhaps mysterious lines - are written according to the vocabulary and grammar of the C++ programming language (they may contain mistakes for now). Here is a brief explanation of what they mean:

double r: We are informing the compiler to reserve memory for a variable named r. That variable will contain a decimal number, which in C++ are called "double".
cin >> r: The cin statement "connects" the keyboard to the variable r. It has the effect that anything the user types will be redirected into the variable r as soon as the user hits the RETURN key.
double V = 4.0 / 3.0 * Pi * r^3: This statement actually accomplishes two things simultaneously. First, it defines a new variable V which will again be of type "double" (i.e. a decimal number). Also, it computes a number according to the formula 4.0 / 3.0 * Pi * r^3 and stores the result in the variable V that was just defined.
cout << V: Just as the cin >> r statement connects the keyboard to the variable r, this statement connects the variable V to the screen. In effect, the value of V will appear on the screen.

Our program is finished, or at least we hope it is finished. We would now save this program in a file that we might call "volume.cpp", where the cpp extension indicates that our file is a C++ source code file. We can now use a C++ compiler to compile the program and produce the corresponding object code file volume.obj. However, the compiler will not be able to create the object file, because our source code contains errors. The compiler will inform us that

the variable Pi is unknown, or undeclared, and
the operation r^3 is unknown to the C++ compiler.

Stage 3: An error message during the compilation stage is nothing unusual. In fact, it is very common, and you should really think of compiler error messages as helpful hints of how to modify your program so that it adheres exactly to the C++ grammar and vocabulary. In our case, we need to modify our program as follows:

#include <iostream.h>

int main(void)
{
   // defining Pi as a constant
   const double Pi = 3.1415;
   // ask user for the value of the radius
   double r;
   cin >> r;
   // compute the volume of the sphere (V = 4/3 * Pi * r^3)
   double V = 4.0 / 3.0 * Pi * r*r*r; 
   // display the answer on the screen
   cout << V;
   return 0;
}

In other words, we added two lines at the beginning of our program:

The first line is simply a comment, indicating what we are about to do - because it is prefaced by the double-slash - and is therefore ignored by the compiler
The next line informs the compiler that we are planning to use a decimal (or double) variable named Pi which we set to the value 3.1415. We also use the const keyword to indicate that Pi is considered a constant, i.e. its value will not change in our program.

We have also replaced the statement r^3 (which the compiler did not like) by the statement r*r*r. After all, mathematically they mean the same thing, and if the compiler does not like one way (r^3),  perhaps it understands the second way (r*r*r).

After saving this new version again as file volume.cpp, it will compile without any error messages. The compiler will produce a file volume.obj that is no longer readable by "humans" but is the translated version of our source code into 0's and 1's. We can now link the program to produce the executable program. Linking will combine our object file volume.obj together with other object files and save it as volume.exe. One such object file that will be combined with our volume.obj is iostream.obj (which we will discuss later).

We are now ready to execute our program. If we do that, we will simply see a blinking cursor. We need to remember that one of the first things our program does is wait for the user to enter a value for the radius. However, no message informing us appears, because we have not programmed such a message into our program. If we enter the value, say, 2.0, our program will then display another number representing the volume of a sphere with radius 2. But, it will not display a message saying what this number means (because again we did not program that in).


Stage 4: Therefore, we'll improve our program one more time by adding the appropriate "prompts" to it. Here's our code:

#include <iostream.h>

int main(void)
{
   // defining Pi as a constant
   const double Pi = 3.1415;
   // ask user for the value of the radius
   cout << "Please enter the radius: ";
   double r;
   cin >> r;
   // compute the volume of the sphere (V = 4/3 * Pi * r^3)
   double V = 4.0 / 3.0 * Pi * r*r*r; 
   // display the answer on the screen
   cout << "The volume of the sphere is: " << V;
   return 0;
}

This will again compile fine and produce - almost - reasonable output. The final improvements would fall under the details that we will cover later.

(bgw)