C++ Week 1

Elements of a C++ Program

What is the shortest C++ program you can write?

main()
{
}

#includes

These are libraries. When you send the file to the compiler, the preprocessor substitutes the #include with the contents of the specified library file. In this way you can create and use modules that define functions that you only add to your code when you need them. There are lots of different libraries available for many different purposes.

Note that input/output is defined in a library, so if you want your program to be able to do any simple I/O, which you normally do, you need to use #include <iostream>.

Namespaces

A namespace allows you to use your own names without worrying about conflicts with names that other programmers may have used for their own variables etc. However you need to make it explicit that you are using a standard namespace by adding using namespace std;

If you forget to add this line to your code, the compiler will be unable to recognise any of the keywords defined in the libararies you are using, such as cout.

Elements of a program

Output using cout <<

cout is the name of the standard output stream, normally the monitor. The << operator evaluates the argument that follows it and places it in the output stream that precedes it.

Here are some valid cout statements:

cout << "Hello"; // "Hello" is a string literal

cout << 27; // 27 is a value

cout << 2+3; // 2+3 is an expression

cout << "result" << 5+7; // you can concatenate << operators on a line

To end a line of output you can use << "\n" or << endl.

Variables

A variable is a data item stored in a chunk of memory that has been reserved for it. Integer variables are numbers without decimal points. Declare them using e.g. int x;

Or you can declare several on one line, e.g. int x, y, z;

When you declare a variable in C++, you have to state what type of variable it is - what sort of value it is going to store.

Double variables are for floating-point numbers. Declare them using the double keyword. float variables are like doubles but occupy less memory. (A double occupies twice as much memory as a float, hence its name.) Since memory is no longer in such short supply they are falling into disuse.

int and double are examples of types that are part of the core language, sometimes known as "built-in" types. Other types are defined in libraries and can be linked in if required. string is an example of one of these. If you want to use variables of type string, you include the line #include<string>

Variables of built-in types are not initialized for you. If you declare simply int x; the compiler reserves a portion of memory for your program to use as an integer variable, but the contents are whatever happens to be there from the last time this portion of memory was used. We say that the variable's value is undefined.

You can initialize a variable when you declare it (more precisely, when you define it), for example int x = 0; If you don't initialise a variable when you declare it, be sure that, by the time you try to use its value, it does indeed have a value for you to use!

If you are declaring several variables in one line and you want to initialize them all, you have to initialize each one separately. For example:

int x = 1, y = 3;

Strings

If you want to use strings remember to use #include<string>. Nowadays, storage is not the scarce resource that it used to be, and some implementors of C++ choose to include several of the other standard libraries in the iostream library. So you might find, depending on which system you are using, that, just by putting in #include <iostream> you are able to use such things as strings, character functions, mathematical functions and so on which, strictly, require the string, cctype and cmath libraries respectively. But if you want to be sure that your C++ programs will compile and run correctly on any C++ system, you should make a point of including all the library files that your program requires.

Enclose string literals in " ". Strings are not built-in types. If you don't initialize a string explicitly, it will be initialized for you as an empty string "" (that's two double-quote marks together, with no space between).

Reserved keywords

The C++ compiler uses words like int, double, float etc and they are therefore reserved. You cannot use them as variable names.

Identifiers

Identifiers are the names that the programmer invents, for example for variables. They must always begin with a letter; subsequent characters may be a letter, number or underscore _ but not a space or other character. Note that C++ is case-sensitive (i.e. it distinguishes between upper-case and lower-case) so that you could use, for example, num1 and NUM1 in your code as the names of two different variables (the compiler won't get them confused, though you might!); you could use Int as an identifier since it is different from the reserved word int.

Input using cin >>

cin is the name of the standard input stream. By default, this will be the keyboard. The >> operator reads data from the input stream that precedes it and places it in the argument that follows it. Take note of the following characteristics.

the >> operator ignores leading white space (<space>, <newline> and <tab> characters) and takes as its input the first non-space characters it encounters in the input stream (from the keyboard or a file). Thereafter its behaviour depends on the type of variable it is being asked to put data into.

string s; cin >> s;

When reading into a string, >> skips leading white space and reads everything into the string up to but not including the next white space. Remember that "white space" includes <space>, <newline> and <tab> characters.

int x; cin >> x;

When reading into an integer, >> will skip leading spaces and will then accept a '+' or '-' or a digit ('0' to '9') as a leading character and thereafter continues to read in characters, so long as they are digits, until it encounters some other sort of character (white space, non-numeric or decimal point). In the above example, typing +492A will place 492 into x.

double d; cin >> d;

When reading into a double, >> proceeds much as it does for integers except that it will also accept a decimal point if it has not had one already. In the above example, typing .67a will place 0.67 into d (it will accept, but does not require, a leading zero in the input).

Here is an example of how >> behaves when asked to read input into an int, a double and then a string.

int i; double d; string s;
cin >> i >> d >> s;
input i d s
12 5.9 London 12 5.9 London
-3
6.6
Paris
-3 6.6 Paris
33.54 Hong Kong 33 0.54 Hong

In the last of these examples, note how the decimal point terminates the reading of the integer (cin >> i) and is then the first character to be read when it tries to read a double (>> d).

If the wrong sort of data is placed in the input stream then it will fail - for example, if you type a letter when >> is expecting integer data. Once the input stream fails you can use cin.clear() [i.e. input_stream.clear()] to clear the input stream's fail state, but of course you must also do something about the input that caused it to fail; simply trying to read the input again with the same input statement will cause it to fail again. For example, if it failed when you were asking it to read into an integer variable, then, having cleared the fail state, you might ask it to read into a string variable instead.

(The Borland implementation of the string read has an annoying quirk. It consumes the white-space character that terminated the string - it does not put it into the string variable, but it removes it from the input stream. It does not do this when reading into an int or a double. For example, if the input were 245 678 and you read it into an int with cin >> i; you'd get the value 245 into i and the next character to be read would be the space immediately after the 5. If, however, you read it into a string with cin >> s; then s would contain the string "245" but the next character to be read would be the 6.)

Assignment statements

Assignments take the form Variable = Expression

Note: Do not confuse the assignment operator = with the test-for-equality operator ==.

You can combine the = operator with other mathematical operators. For example, x += 5; means x = x + 5; while x /= 20; means x = x / 20;

If you are adding 1 to a variable, or subtracting 1 from it, there is an even shorter shorthand. x++ or ++x will increase x by 1. Similarly x-- and --x will decrease x by 1.

However when you use these auto-increment (++) or auto-decrement (--) operators within expressions, the two versions are not equivalent. When they are used as expressions, we are also interested in the value that they return. ++x and --x return the new value of x while x++ and x-- return the old value of x

y = ++x; //  x = x + 1; y = new value of x; as you'd expect
y = x++; //  x = x + 1; But y = old value of x;
n = 0; while ( ++n < 5) cout << n << " \n"; // outputs 1 to 4
n = 0; while ( n++ < 5) cout << n << " \n"; // outputs 1 to 5

Arithmetic Operators

Arithmetic operators are used in expressions.

+ addition
- subtraction
* multiplication
/ division - if both arguments are integers, the result is truncated to an integer, otherwise the result is a floating point number.
% modulo - the remainder of the division of two integers.

If you have an expression without explicit parentheses, you need to know where the implicit parentheses go. For example, if you have

2 + 3 * 4
you need to know whether this means
(2 + 3) * 4
or
2 + (3 * 4)
This is decided by reference to a table of operator precedence. Every operator in the language has its place in the precedence table. For the arithmetic operators, the operators *, / and % take precedence over + and -. So
2 + 3 * 4
means
2 + (3 * 4)

If the operators are of equal precedence, we need to know their associativity, i.e. whether we take them left to right or right to left. These five arithmetic operators are all left-associative, meaning that, for example,

8 - 5 - 3
is taken as
(8 - 5) - 3
and not
8 - (5 - 3)

We can apply these rules to the following expression:

1 + 2 - 3 * 4 / 5 % 6
1 + 2 - (3*4) / 5 % 6
1 + 2 - 12 / 5 % 6
1 + 2 - (12 / 5) % 6
1 + 2 - 2 % 6
1 + 2 - (2 % 6)
1 + 2 - 2
(1 + 2) - 2
3 - 2
1

When using the shorthand forms of assignment, note that the expression on the right-hand side is implicitly parenthesised, because these operators (+=, *= and so on) occupy a lowly place in the precedence table. So, for example,

x *= y + 2
means
x = x * (y + 2)

Type conversion

If you assign an integer value to a variable of type double, the value is cast (type-converted) into a double. Conversely, if you assign a double to an integer variable the value is truncated. An expression that contains an int paired with a double is evaluated to a double. For example:

int i = 16;
double d;
d = i; // d = 16.0
d = 10.7;
i = d; // i = 10  (truncation, not rounding)
cout << 2 * 3.4 + 7 / 2; // 6.8 + 3 = 9.8 (a double)

Note that integer division is performed between 7 and 2 in this example, because both operands are integers. (A numeric constant with no decimal point is of type int, and one with a decimal point is a double.)

String manipulation

If you try to use a >> operator to input a string that consists of several words, you will get only the first word - it stops at the first space. If you want to input more than one word into a string variable, you should use the getline procedure - getline(stream, variable); This places the whole line up to the <EOL> character into the string variable and consumes the <EOL> character (i.e. places you at the start of the next line).

If you are at the start of a line when you execute a getline, you get the whole of the line. If you are already some way through the line, for example as a result of having used the input operator >>, then getline will give you the rest of the line.

You have to be a bit careful if you use both the >> operator and a getline(cin, s); For example, suppose the input were:

234
Chipping Sodbury
You might think that the following would read the number into x and the string into name:
cin >> x;
getline(cin, name);
But, though you'd get the number 234 into x, you actually wouldn't get "Chipping Sodbury" into name. In fact, name would contain an empty string. You have to remember that the newline character counts as white space. The integer read stops immediately after the 4, i.e. before the newline character. The getline(cin, s); then puts all the characters from there to the end of the line (there are none) into name and consumes the newline character, leaving you immediately before the C of "Chipping".

In order to get past the newline character, you could do an extra getline, as in:

cin >> x;
getline(cin, junk);	// just consumes the newline character
getline(cin, name);
or you could use the ignore function, as in
cin >> x;
cin.ignore();	// skips one character, in this case the newline character
getline(cin,name);

Substrings

You can extract substrings from a string using the substr() member function.

s.substr(start_position, substring_length);

For example if the string s is "department", the code:

cout << s.substr(2, 4);

outputs the substring "part". The letter 'p' is at position 2 because the first character of a string is in position zero.

You can leave out the second argument to the substr function, in which case it will return the whole of the rest of the string. For example, s.substr(6) will return "ment".

Note that you cannot assign to a substring. You cannot say s.substr(6,4) = "ures" and expect to get "departures".

Concatenation

Strings can be concatenated using the + operator. The use of the "+" operator to do two quite different tasks (arithmetic addition and string concatenation) is an example of operator overloading. You can concatenate string variables and literals, on condition that the concatenation expression contains at least one string variable.

string s = "abc";
string t = "def";
string z = s + t; // z = "abcdef"
z = "Letters " + s + " More letters"; // Valid code  
z = "Letters " + " More letters";  // Invalid code (no string variable)

Finding the length of a string

The function length() returns the length of a string. Note that the index of the last character of a string is one less than the length of the string. For example, to determine the last character of the string s, use the following code:

string z = s.substr(s.length() - 1, 1);

Note that you cannot assign to length() It might be tempting to think that you could change the length of a string by saying something like s.length() = 5 but you can't.

Formatting the output stream

To specify that an item in the output stream should be allocated five columns, insert << setw(5) before the item in the output statement. For example:

cout << "x" << setw(5) << 133  << "x";

produces the output

x  133x

The 133 is right-justified in a five-character field. setw() only affects the next item in the output stream.

If you want to specify the number of decimal places, use setprecision() with fixed. This is often required if you need to specify that trailing zeroes are used (e.g. when displaying currency). fixed and setprecision() affect all subsequent items in the output stream, so you only need to use them once.

double d = 6.0;
cout << d; // (without fixed and setprecision) puts 6 (not 6.0) in the output stream
cout << fixed << setprecision(1) << d; // puts 6.0 in the output stream
cout << fixed << setprecision(3) << 123.456789; // 123.457 (3 dec places, with rounding)

To use these output stream manipulators, you need to #include <iomanip>


Notes on R. Mitton's lectures by S.P. Connolly, edited by R. Mitton, 2000