Pre-processor directive—tells the compiler to insert code from another file (typically declarations of other functions).
#include <iostream>
Code from the iostream file is inserted exactly as if you had typed it in yourself.
tells the compiler where to look for definitions that aren't defined in our program.
using namespace std;
Every program must have a main
function. It is the starting point
of program execution. This is what it looks like
int main() { // the function body goes here }
When execution reaches the end of main
, the program terminates.
We're going to introduce our first syntax definition here:
int square(int num){
return num * num;
}
Interpretation: the square of num
is computed
and the int
result returned.
main
is actually a function returning value, which means it fits
this form.
Both main
and square
return an integer value (int
).
In the case of square
the value returned (the output) represents
the square of num
, the value input.
In the case of main
, the return value is actually passed to the
operating system after the program is run. Normally it will be zero, meaning
your program ran successfully. Other numbers represent codes for various kinds
of errors. In this course we will generally return just 0;
This drawing looks at just the pre-compile / compile process. The two work invisibly as a pair. It looks like one process to the programmer. Any instruction that begins with a hash mark (#) is actually an instruction to the pre-compiler, the programmer's automated administrative assistant. Here the assistant strips out all the comments and
fetches the code from the The resulting code the compiler gets is much reduced except thatall code from the header file has been added. We don't show it because it's too complex. The compiler checks the reultant code for syntax errors. If it finds any it will generate a report Only if the code is grammatically correct will an output file be generated. |
![]() |
cout << expression;
—output the value of expression
to the standard output (screen) stream.
cout << "Hello world!" << endl;
<<
is a left associative operator -- expressions are ouput
left-to-right.
endl
causes an newline ('\n'
) character to be output.
cin >> x;
—Read a value from the standard input stream
(usually the keyboard) and store it in the variable named x
.
cin
is an identifier for the standard input stream
(keyboard) .
string bookTitle;
bookTitle = "Programming in C++";
Strings can be joined with '+'
.
C++ treats inputs and outputs as streams of data—that is piece of data after piece of data after piece of data, flowing one after another as if in a stream.
There are three standard streams, only two of which we need to be concerned with (the third is an error stream, used for reporting errors, and works just like the output stream).
The standard output stream. Data is inserted into the standard output stream using the insertion operator, << , for example,
cout << "The value of x is " << x << endl;
This means that the string literal "The value of x is "
is
first inserted into cout
, then the current value of x
is
inserted and finally a special token endl
is tossed in which tells
the cout
stream that the line has ended.
In this course the standard output stream will almost always be attached to
the console window. Assuming x
is currently 3.76
,
you would see
The value of x is 3.76
displayed on a console window on your computer screen.
cout
is a pretty smart object and knows how to display data of
almost any type properly.
The standard input stream. Data is extracted from it using the standard extraction operator, >> , for example
double x;
int i;
cin >> x >> i;
declares a double
variable x
, an int
variable i
and
then extracts values for them from the input stream, cin
. cin
will
almost always be connected to the keyboard in this course.
It's hard for a user to enter data into a program unless the programmer tells the user what is wanted. That is your program must prompt the user for input. Do this by mixing input and output commands as follows.
double cost;
int quantity;
cout << "Please input the unit cost: ";
cin >> cost;
cout << endl << "And now the number of items: ";
cin >> quantity;
cout << endl;
Note that by not inserting an endl
at the end of the first cout
statement
we leave the cursor at the end of the prompt. Then we start the next cout
with
an endl
moving the second prompt (and input) onto its own line.
Arguments in the original C language were always passed by value. This was done to avoid side effects. Consider a little different version of the factorial function:
Code Notes
1. Don't forget that, as the expression engine will show you,
the line result *= n--
is equivalent to result = result * n--
2. As usual, to evaluate n
the TM looks the value
of n
up in memory. The effect of the post decrement is to decrement n
after
it has fetched the value. To see it in detail, step through the expression
in the expression engine and watch the fetch-execute cycle closely.
The line
result *= n--;
actually contains two potential side effects. Let's focus first on the one caused by decrementing in the middle of an expression.
The line is equivalent to the following two lines
result *= n; n--;
That is the original, in one line, both
result
(the main effect)
as well asn
(the side effect).But when are we decrementing n
? Notice in this second version
it is very clear that n
is decremented after we used its previous
value.
When we increment or decrement, there are actually two forms of the operators, known as post-decrement (or post-increment) and pre-decrement (or pre--increment). In the example above the decrement operator is said to be in the post position (it comes after the variable being decremented).
It is perfectly grammatically correct to put the decrement operator before the variable as:
result *= --n;
but now it means something different. Again, writing it as two lines we would need to write it this way—
n--; result *= n;
Putting an increment/decrement operator in the pre- position means that the increment/decrement operation is carried out before the value of the variable is used.
Here is the same program ammended to use pre-decrement. Step through both versions in the teaching machine to see the difference
Code Notes
1. As usual, to evaluate n
the TM looks the value
of n
up in memory. The effect of the pre-decrement is to decrement n
before
it fetches the value. Thus the value fetched is the new value. To see
it in detail, step through the expression in the expression engine and watch
the fetch-execute cycle closely.
2. To deal with the differences we had to preset result
to n
because
the very first time we multiply we will actually be using n-1
We also changed the test to n > 2
because by
the time we carry out the test the multiplication has already been done. The
answer would still have been correct but we would have passed through the loop
an extra time unnecessarily.
You might consider how you could re-write the first (post-decrement) version to have one less passes through the loop.
While this second version works it is far less understandable than the first.
In fact, in general we regard incorporating incrementing into expressions as a side effect to be quite advanced programming
increment/decrement operators should never be incorporated into expressions on variables that are used more than once in the expression.
For example
y = ++n * log(n);
should never be used. The n
is incremented on the memory fetch
part of the evaluation cycle and there is no way to predict which n
optimizing
compilers will decide to fetch first.
From Arrays
Problem: Find the median grade for a class.
Analysis:
1. We're going to need an array to hold the grades. How big should it be?
If we want to handle different classes, we won't know the class size until we read the data in from the file (which is when we run the program). But we have to size the array when we build the program.
One approach is to create an array large enough to handle any reasonable class size and then only use part of it. We'll also have to watch out for a class bigger than we planned for.
So we'll pick a
MAX_CLASS_SIZE
and declare afloat grades[MAX_CLASS_SIZE]
2. Clearly we're going to have to read the data in from a file. That should probably be done by a function.
We should give the function the array and tell it about MAX_CLASS_SIZE and then let it tell us the actual size
3. In order to find the median we're going to have to sort the file into either ascending or descending order. Another funtion. It will need the grades array and the actual class size.
4. compute the median.
Major Data:
int MAX_CLASS_SIZE
float grades[MAX_CLASS_SIZE]
Headers:
int getGrades(float gradeData[], int maxSize) // return actual size
void sort(float gradeData[], int size)
Algorithm:
Read values into grades[0..N-1]
Sort grades in increasing order
if N is even
median = (vals[N/2-1] + vals[N/2]) / 2
else
median = vals[N/2]
Final Comment:
Why N/2 in the last line?
If N is odd, for example 5
- There are 5 elements in the array
- They are numbered from 0 to 4
- The middle one is no 2 (0, 1, 2, 3, 4)
- N/2 is of course 2
Here is the example we worked out in class, recut for the Teaching Machine. The sort routine is shown here.
Code Notes
1. This sort function is a classic example of a double loop. The way to understand it is to focus on the inner loop.
2. What the inner loop does is to compare the
i
'th element of the array with every element that comes after it. If any element is bigger than thei
'th one it is swapped with it. Thus, at the end of a pass through the inner loop, the largest element after thei
'th one has replaced it, like the largest bubble floating to the top.3. The function of the outer loop, then, is to pick
i
. Start with element0
(theTable[0]
) and use the inner loop to "bubble" the largest element in the whole array to position0
. Then go to position1
and "bubble" the next largest element into that position. And so on, to the third largest in the position2
, 4'th largest in3
, until we finally reach the second last position in the array.4. When the outer loop gets
i
to the second last position, the inner loop only has to check the last position. Either the last element is bigger than the second last (in which case they are swapped) or it isn't. Either way, we're done. There's no reason to seti
to the last postion because there's nothing that comes after it for the inner loop to work on.
Of course it uses the swap routine we developed earlier.
Then the median is computed by putting it all together as shown here.
(Copied in from pass-by-reference)
The display above doesn't actually show the getFloat
function implementation or declaration. If you've run the example in the TM already you may have noticed something strange about them. Here's the implementation.
What's up with the const keyword in the function prototype
double getDouble( const string& what)
In the first place why not just pass the string by value as we would normally do? After all we don't want to change it. It's just input for the function.
Remember that pass-by-value means a copy gets made. In this case a full copy of the string object (although you won't see it reflected in your simple memory model on the TM—it's done behind the scenes in another part of memory called the heap that we won't talk about until the advanced course). Making such a copy is potentially very expensive because strings can be very large.
Passing-by-reference suppresses copying. The only thing passed into the function is the reference to the original object (which is about the size of an int
or long
).
However, there is an implication when we pass by reference that the variable will be modified.
The const
tells the compiler (and more importantly, any clients who are going to use our function) that although prompt
is being passed by reference it will not be modified. In other words, it is read-only.
Here are the examples shown in class;
Computer programs have to be built. We use a number of processes (computer programs) to build a program
An editor is a specialized word processor used to prepare source modules in the language of choice (e.g. C++, Java, Fortran, Basic) The precompiler adds in standard pre-written code (boilerplate) from include files you specify to produce a complete source module. The precompiler is like a secretary that helps you pull together a full source document. The compiler produces object code for the target computer/operating system. The compiler is like a translator that converts your module from the language of your choice (C++) to language the computer (PC, MAC, Sun) understands. The linker ties multiple modules together into a complete program
|
![]() |
An executable is a program that will run on the computer. The editor, precompiler, compiler and linker are all executables.
So is your program!