A short introduction to computer programming, using C++

Roger Mitton, Birkbeck, University of London

Chapter 3

Loops

How would you write a program to add up a series of numbers? If you knew that there were, say, four numbers, you might write this program:

#include <iostream>
using namespace std;
int main()
{   int num1, num2, num3, num4;
    cout << "Please key in four numbers: ";
    cin >> num1 >> num2 >> num3 >> num4;
    int total = num1 + num2 + num3 + num4;
    cout << total << endl;
}
But a similar program to add up 100 numbers would be very long. More seriously, each program would be tailor-made for a particular number of numbers. It would be better if we could write a program to handle any series of numbers. We need a loop.

One way to create a loop is to use the keyword while. For example:

#include <iostream>
using namespace std;
int main()
{    int num = 0;
     while (num < 100)
     {    num = num + 5;
          cout << num << endl;
     }
}

Having initialized the variable num to zero, it checks whether the value of num is less than 100. It is, so it enters the loop. Inside the loop, it adds 5 to the value of num and then outputs this value (so the first thing that appears on the screen is a 5). Then it goes back to the while and checks whether the value of num is less than 100. The current value of num is 5, which is less than 100, so it enters the loop again. It adds 5 to num, so num takes the value 10, and outputs this value. It goes back to the while, checks whether 10 is less than 100 and enters the loop again. It carries on doing this with num getting larger each time round the loop. Eventually num has the value 95. 95 is less than 100 so it enters the loop again, adds 5 to num to make it 100 and outputs this number. Then it goes back to the while and this time sees that num is not less than 100. So it stops looping and goes on to the line beyond the end of the loop. (In the case of this program, there are no more lines, so it finishes.) The output of this program is the numbers 5, 10, 15, 20 and so on up to 95, 100.

Note the use of curly braces to mark the start and end of the loop. Each time round the loop it does everything inside the curly braces. When it decides not to execute the loop again, it jumps to the point beyond the closing brace.

What would happen if the while line of this program was while (num != 99)? The value of num would eventually reach 95. The computer would decide that 95 was not equal to 99 and would go round the loop again. It would add 5 to num, making 100. It would now decide that 100 was not equal to 99 and would go round the loop again. Next time num would have the value 105, then 110, then 115 and so on. The value of num would never be equal to 99 and the computer would carry on for ever. This would be an example of an infinite loop.

Note that the computer makes the test before it enters the loop. What would happen if the while line of this program was while (num > 0)? num begins with the value zero and the computer would first test whether this value was greater than zero. Zero is not greater than zero, so it would not enter the loop. It would skip straight to the end of the loop and finish, producing no output.

It is not essential to indent the lines inside the loop, but it makes the program easier to read and it is a good habit to get into.

Exercise 3A

Write a program that outputs the squares of all the numbers from 1 to 10, ie the output will be the numbers 1, 4, 9, 16 and so on up to 100.

To check your answers, click on Answers to the exercises.

Booleans (true/false expressions)

So far we have just used integer and string variables. But we can have variables of other types and, specifically, we can have boolean variables, which in C++ are variables of type bool. (The word "boolean" was coined in honour of an Irish mathematician of the nineteenth century called George Boole.) A variable of type bool does not hold numbers; it can hold just the values true and false. We might declare and initialize a boolean variable thus:

bool positive = true;
Note that we do not have quote marks around the word true. true, without quote marks, is not a string; it's the name of a boolean value. Contrast it with:
string stringvar = "true";
stringvar is a string variable which is being initialized with the four-character string "true". We could assign any other string to stringvar. positive, by contrast, is a boolean variable. We cannot assign strings to positive. It can hold only the values true or false.

You have already met boolean expressions. They are also called conditional expressions and they are the sort of expression you have in brackets after if or while. When you evaluate a boolean expression, you get the value true or false as the result.

Consider the kind of integer assignment statement with which you are now familiar:

num = count + 5;
The expression on the right-hand side, the count + 5, is an integer expression. That is, when we evaluate it, we get an integer value as the result. And of course an integer value is exactly the right kind of thing to assign to an integer variable.

Now consider a similar-looking boolean assignment statement:

positive = num >= 0;
The expression on the right-hand side, the num >= 0, is a boolean expression. That is, when we evaluate it, we get a boolean value (true/false) as the result. And of course a boolean value is exactly the right kind of thing to assign to a boolean variable. You can achieve the same effect by the more long-winded:
if (num >= 0)
     positive = true;
else positive = false;
The variable positive now stores a simple fact about the value of num at this point in the program. (The value of num might subsequently change, of course, but the value of positive will not change with it.) If, later in the program, we wish to test the value of positive, we need only write
if (positive)
You can write if (positive == true) if you prefer, but the == true is redundant. positive itself is either true or false. Once the computer has evaluated positive (established whether it is true or false) there is nothing more to do. We can also write
if (not positive)       // (! positive) on some compilers
which is the same as if (positive == false) If positive is true, then not positive is false, and vice-versa. (If you are using a compiler which hasn't caught up with the current standard, such as g++ or Microsoft Visual C++, you have to use "!" instead of not, ie you have to write if (!positive) instead of if (not positive). These compilers do not understand the word not.)

Boolean variables are often called flags. The idea is that, leaving aside subtleties such as half-mast, a flag has basically two states – either it's flying or it isn't.

So far we have constructed simple boolean expressions using the operators introduced in the last chapter — (x == y), (s >= t) and so on — now augmented with not. We can make more complex boolean expressions by joining simple ones with and and or. For example, we can express "if x is a non-negative odd number" as if (x >= 0 and x % 2 == 1) We can express "if the name begins with an A or an E" as if (name.substr(0,1) == "A" or name.substr(0,1) == "E"). The rules for evaluating and and or are as follows:
.leftandrightleftorright
1truetruetruetruetruetrue
2truefalsefalsetruetruefalse
3falsefalsetruefalsetruetrue
4falsefalsefalsefalsefalsefalse
Taking line 2 as an example, this says that, given that you have two simple boolean expressions joined by and and that the one on the left is true while the one on the right is false, the whole thing is false. If, however, you had the same two simple expressions joined by or, the whole thing would be true. As you can see, and is true only if both sides are true, otherwise it's false; or is false only if both sides are false, otherwise it's true.

As with not, you will find that some compilers do not understand the words and and or. For those compilers, you have to use && for and and || for or.

Exercise 3B

Given that x has the value 5, y has the value 20, and s has the value "Birkbeck", decide whether these expressions are true or false:

(x == 5 and y == 10)
(x < 0 or y > 15)
(y % x == 0 and s.length() == 8)
(s.substr(1,3) == "Bir" or x / y > 0)

To check your answers, click on Answers to the exercises.

Back to loops

Returning now to the problem of adding up a series of numbers, have a look at this program:

#include <iostream>
using namespace std;
int main()
{    bool finished = false;
     int total = 0;
     while (not finished)
     {    int num;
          cin >> num;
          if (cin.fail())
                finished = true;
          else  total = total + num;
     }
     if (cin.eof())
          cout << "Total is " << total << endl;
     else cout << "Invalid input" << endl;
}
If we want to input a series of numbers, how will the program know when we have put them all in? That is the tricky part, which accounts for the added complexity of this program.

The bool variable finished is being used to help us detect when there are no more numbers. It is initialized to false. When the computer detects that there are no more numbers to input, it will be set to true. When finished is true, it means that we have finished reading in the input. (More precisely it means that the input has failed, as I will explain shortly, but the reason for this is usually that there is no more input.) The while loop begins by testing whether finished is true or not. If finished is not true, there is some more input to read and we enter the loop. If finished is true, there are no more numbers to input and we skip to the end of the loop.

The variable total is initialized to zero. Each time round the loop, the computer reads a new value into num and adds it to total. total holds the total of all the values input so far.

Actually it only adds num to total if the input has been successful. There are two main reasons why the input might fail. The first is that there are no more numbers to input. The user will signal that there are no more numbers by keying in a special character. (On Unix this is a Control-D; on PCs it is usually a Control-Z. If this is gobbledygook to you, just imagine that the user strikes a special key on the keyboard.) The other reason why the input might have failed is that what was entered was not an integer — perhaps the user entered a letter or a punctuation mark. If the program is expecting an integer and instead receives something like "abc" or "W" or "**!", the input will fail. We can test whether the input has failed, for whatever reason, with the line if (cin.fail()). If this is true, the input has failed and we set finished to true in order to terminate the loop.

When we exit from the loop, we know that the input has failed for one reason or another, but we do not know exactly why. Perhaps there were no more numbers or perhaps the input was invalid. We can test whether we had reached the end of the input with the test if (cin.eof()). eof stands for "end of file". If this is true then we know there were no more numbers to input and we output the total. If it is false, then the input must have failed for some other reason.

A real-life program ought not to respond to a user error by aborting with a terse error message, though regrettably many of them do. However, dealing with the problem properly would make this little program more complicated than I want it to be at this stage.

You have to take some care in deciding whether a line should go in the loop or outside it. This program, for example, is only slightly different from the one above but it will perform differently:

#include <iostream>
using namespace std;
int main()
{    bool finished = false;
     int total;
     while (not finished)
     {    total = 0;
          int num;
          cin >> num;
          if (cin.fail())
                finished = true;
          else  total = total + num;
     }
     if (cin.eof())
          cout << "Total is " << total << endl;
     else cout << "Invalid input" << endl;
}
It resets total to zero each time round the loop. So total gets set to zero, has a value added to it, then gets set to zero, has another value added to it, then gets set to zero again, and so on. When the program finishes, total does not hold the total of all the numbers, just the value zero.

Here is another variation:

#include <iostream>
using namespace std;
int main()
{    bool finished = false;
     int total = 0;
     while (not finished)
     {    int num;
          cin >> num;
          if (cin.fail())
                finished = true;
          else
          {     total = total + num;
                cout << "Total is " << total << endl;
          }
     }
}
This one has the cout line inside the loop, so it outputs the value of total each time round the loop. If you keyed in the numbers 4, 5, 6, 7 and 8, then, instead of just getting the total (30) as the output, you would get 4, 9, 15, 22 and then 30.

Exercise 3C

Write a program that reads a series of numbers and then tells you how many numbers you have keyed in. For example, if you keyed in the numbers 5, 10, 50, 22, 945, 12, it would output 6.

To check your answers, click on Answers to the exercises.

#include, using namespace, and main

A final word about those mysterious lines that you have to put into your program. When you send your program to the compiler, it actually goes first to another piece of software called the preprocessor. The preprocessor handles the lines beginning with "#". When it comes to a #include line, it removes the line and replaces it with a file of C++ which is stored as part of the system software. This file is called a library header file. The line #include <iostream> is replaced by the iostream library header file. If you intercepted your program after it had left the preprocessor but before it reached the compiler, you would find that there were large amounts of C++ that you didn't recognize and then the program that you had written, tiny by comparison, on the end.

The purpose of these libraries is to provide the programmer with extensions to the language which can be pulled in, as and when needed. If you want to use the string data type, you have to include the string library. If you wanted to use the mathematical functions (square-root, cosine, logarithms etc), you would include the cmath library, and so on. The iostream library contains what's needed for doing input and output. If you didn't include the iostream library, you couldn't use cin and cout.

Some libraries, known as the standard libraries, are provided with every C++ implementation. Other libraries can be created for special purposes. One team of programmers might produce a library of routines for another team of programmers to use. When teams of programmers divide up the work on a large program in this way, it is all too easy for programmers in team A to choose a name for some item in their library and for programmers in team B to choose the same name for some quite unrelated item elsewhere in the program. This can be a serious nuisance. To help contain the problem, C++ provides namespaces. Team A declares one namespace and team B declares another. Now it doesn't matter if they accidentally choose the same name. Team B can still use names from A's namespace, but they have to tell the compiler specifically which names they are going to use.

All the names in the standard libraries are declared in a namespace called std. So, if you are going to use names from these libraries, such as cin and cout, you have to tell the compiler that you are going to use names from the std namespace. It is possible to do this separately for each name, but it's a lot easier to say, just once, that you want your program to be able to use any of them. Hence the line using namespace std; If the compiler seems not to know what you mean by perfectly ordinary bits of C++ such as cin and cout, check that you have not forgotten the using namespace std;

Finally, what is int main()? This is the first line of a program unit, known as a function, which extends from the int to the final "}". A program ordinarily consists of many functions. The main function is the one that gets executed first. Every C++ program must have a main function. You'll understand why the word main is preceded by the word int and followed by () when you have learnt about functions. This topic is covered in chapter 4; you don't have to read this before the interview, but you are recommended to read it before starting the MSc.

Exercises

Exercise X1

What does this program do?

#include <iostream>
using namespace std;
int main()
{    bool finished = false;
     int m = 0;
     while (not finished)
     {    int num;
          cin >> num;
          if (cin.fail())
                finished = true;
          else
               if (num > m)
                     m = num;
     }
     cout << m << endl;
}

Exercise X2

If you have worked out what the above program does, can you see that, for certain series of numbers, it will not produce the correct output? In what circumstances will it not work correctly, and how could you change the program to make it work properly?

Exercise X3

Write a program that takes a series of numbers and counts the number of times that the number 100 appears in the list. For example, for the series 2, 6, 100, 50, 101, 100, 88, it would output 2.

Exercise X4

Write a program that takes a series of lines and, at the end, outputs the longest line. You may assume there is at least one line in the input.

Exercise X5 (this one is a bit harder)

Write a program that takes a series of numbers. If the current number is the same as the previous number, it says "Same"; if the current number is greater than the previous one, it says "Up", and if it's less than the previous one, it says "Down". It makes no response at all to the very first number. For example, its output for the list 9, 9, 8, 5, 10, 10, would be Same, Down, Down, Up, Same (comparing, in turn, 9 and 9, 9 and 8, 8 and 5, 5 and 10, 10 and 10). You may assume there are at least two numbers in the input.

To check your answers, click on Answers to the exercises.

A short introduction to computer programming, using C++

Summary of the language features mentioned in this introduction

#include <iostream>Start and end your programs like this.
using namespace std;
int main()
{
Your program goes here
}
#include <string>Extra line if you are going to use strings
//Introduces a comment
int i;Defines an integer variable called i
int x, y;Defines integer variables called x and y
bool b;Defines a boolean variable called b
string s;Defines a string variable called s
int num = 0;Defines and initializes an integer variable called num
cin >> num;Takes a value from the input and puts it into num
cin >> x >> y;Takes values from the input and puts them into x and y
cin >> sTakes a string from the input (ignoring leading spaces) and puts it into s
getline(cin,s);Takes a whole line from the input and puts it into s
cout << num;Outputs the value of num
cout << "The answer is " << x;Outputs "The answer is " followed by the value of x
cout << s << x;Outputs the value of s followed by the value of x
cout << endl;Outputs an end-of-line
x = 99;Assigns the value 99 to x
+, –, *, /, %Arithmetic operators. *, / and % take precedence over + and –
Division with integers gives an integer (not floating-point) result.
s.length()Gives length of string s
s.substr(x, y)Gives substring of s starting at character x and of length y
(The first character of the string is character zero.)
if (A) B; else C;If A is true, do B, else do C.
(x == y)Tests whether x is equal to y. Note double "="
!=, >, <, >=, <=Not equal to, greater than, less than, etc
{Used to bracket together separate statements
}to make them into a block
while (A) B;While A is true, do B. B can be a block.
true, falseThe boolean values true and false.
not, and, orThe boolean operators not, and and or (on some compilers !, && and ||).
(cin.fail())Tests whether the most recent attempt to input something failed.
(cin.eof())Tests whether the program has reached the end of the input.

Obtaining, installing and running a C++ compiler on a PC

If you intend to use your own PC for doing assignments on the MSc course, we want you to use the Borland C++ compiler. You can download a free copy of this. A link to the site and some documentation on the installation is available on the departmental website at www.dcs.bbk.ac.uk/support/borlandfreecpp.pdf

Compiling and running programs

The Borland is a command line compiler. You first type your program in a text editor. Notepad will do. If you use a word-processor, make sure you save the file as text. Give the filename a .cpp extension.

Open a DOS Window (Command Prompt from the Start Menu.)

Change to the directory (folder) where you have saved your program. (You don't have to do this but it's easier if you do, otherwise you have to type the full path for your source code file.) Suppose your program is in a file called myprog.cpp If compiling with the Borland compiler, you would type

bcc32  myprog.cpp
to compile the program. If compilation was successful you would be returned to the prompt. The compiler would make an executable file called myprog.exe, and you would type myprog to run your program. If there were errors you would get error messages and you would need to go back to the text editor, correct and save the program again, then recompile.

Remember that, with the Borland compiler (and many others), you need to use &&, || and ! for and, or and not.