Chapter 1
Chapter 1
You are already familiar with character arrays, which are the only method for storing character
strings in the C++ language. It isn’t the only kind of array you can use. There is an array for
every data type in C++. By learning how to process arrays, you greatly improve the power and
efficiency of your programs. An array consists of a set of objects (called its elements), all of
which are of the same type and are arranged contiguously in memory. In general, only the array
itself has a symbolic name, not its elements. Each element is identified by an index which
denotes the position of the element in the array. The number of elements in an array is called its
dimension. The dimension of an array is fixed and predetermined; it cannot be changed during
program execution.
Arrays are suitable for representing composite data which consist of many similar, individual
items. Examples include: a list of names, a table of world cities and their current temperatures, or
the monthly transactions for a bank account. Therefore, an array variable is defined by specifying
its dimension and the type of its elements.
For example, an array representing 10 height measurements (each being an integer quantity) may
be defined as:
int heights[10];
The individual elements of the array are accessed by indexing the array. The first array element
always has the index 0. Therefore, heights [0] and heights [9] denote, respectively, the first and
last element of heights. Each of heights elements can be treated as an integer variable. So, for
example, to set the third element to 177, we may write:
heights[2] = 177;
Attempting to access a nonexistent array element (e.g., heights [- 1] or heights [10]) leads to a
serious runtime error (called ‘index out of bounds’ error). Processing of an array usually involves
a loop which goes through the array element by element. Like other variables, an array may
1|Page
have an initialize. Braces are used to specify a list of comma- separated initial values for array
elements. For example,
Initializes the three elements of nums to 5, 10, and 15, respectively. When the number of values
in the initialize is less than the number of elements, the remaining elements are initialized to
zero:
int nums[3] = {5, 10}; // nums[2] initializes to 0
When a complete initialize is used, the array dimension becomes redundant, because the number
of elements is implicit in the initializer. The first definition of nums can therefore be
equivalently written as:
Multidimensional Arrays
An array may have more than one dimension (i.e., two, three, or higher). The organization of the
array in memory is still the same (a contiguous sequence of elements), but the programmer’s
perceived organization of the elements is different.
For example, suppose we wish to represent the average seasonal temperature for three Ethiopian
cities (see Table 1. 1).
Dessie 26 34 22 17
Addis Ababa 24 32 19 13
Dire Dawa 28 38 25 20
This may be represented by a two- dimensional array of integers:
int seasonTemp[3][4];
2|Page
As before, elements are accessed by indexing the array. A separate index is needed for each
dimension. For example, Dessie’s average summer temperature (first row, second column) is
given by seasonTemp[0][1] .
int seasonTemp[3][4] = {{26, 34, 22, 17},{24, 32, 19, 13},{28, 38, 25, 20}};
Because this is mapped to a one- dimensional array of 12 elements in memory, it is equivalent to:
int seasonTemp[3][4] = {26, 34, 22, 17, 24, 32, 19, 13, 28, 38, 25, 20};
The nested initialization is preferred because as well as being more informative, it is more
versatile. For example, it makes it possible to initialize only the first element of each row and
have the rest default to zero:
We can also omit the first dimension (but not subsequent dimensions) and let it be
int seasonTemp[][4] = {{26, 34, 22, 17},{24, 32, 19, 13},{28, 38, 25, 20}};
Processing a multidimensional array is similar to a one- dimensional array, but uses nested loops
instead of a single loop.
1.2. Working with String
In all programs seen until now, we have used only numerical variables, used to express numbers
exclusively. But in addition to numerical variables there also exist strings of characters that allow
us to represent successions of characters, like words, sentences, names, texts, et cetera. Until now
we have only used them as constants, but we have never considered variables able to contain
them.
3|Page
In C++ there is no specific elemental variable type to store strings of characters. In order to
fulfill this feature we can use arrays of type char, which are successions of char elements.
Remember that this data type (char) is the one used to store a single character, for that reason
arrays of them are generally used to make strings of single characters.
name
This maximum size of 20 characters is not required to be always fully used. For example, name
could store at some moment in a program either the string of characters "Hello" or the string
"Good Morning". Therefore, since the array of characters can store shorter strings than its total
length, there has been reached a convention to end the valid content of a string with a null
character, whose constant can be written 0 or '\0'.
We could represent name (an array of 20 elements of type char) storing the strings of characters
"Hello" and "Good Morning" in the following way:
name
H e l l o \0
G o o d M o r n i n g \0
Notice how after the valid content it is included a null character ('\0') in order to indicate the end
of string. The panels in gray color represent indeterminate values.
Initialization of strings
Because strings of characters are ordinary arrays they fulfill all their same rules. For example, if
we want to initialize a string of characters with predetermined values we can do it in a similar
way to any other array:
4|Page
char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In this case we would have declared a string of characters (array) of 6 elements of type char
initialized with the characters that compose Hello plus a null character '\0'.
Nevertheless, string of characters have an additional way to initialize its values: using constant
strings.
In some expressions string of characters can appeared several times as a constants that
represented entire strings of characters. These are specified enclosed between double quotes ("),
for example:
Unlike single quotes (') which allow to specify single character constants, double quotes (") are
constants that specify a succession of characters. These strings enclosed between double quotes
have always a null character ('\0') automatically appended at the end.
Therefore we could initialize the string mystring with values by any of these two ways:
In both cases the Array or string of characters mystring is declared with a size of 6 characters
(elements of type char): the 5 characters that compose Hello plus a final null character ('\0')
which specifies the end of the string and that, in the second case, when using double quotes (") it
is automatically appended.
Before going further, it is better to notice that the assignation of multiple constants like double-
quoted constants (") to arrays are only valid when initializing the array, that is, at the moment
when declared. Expressions within the code like:
mystring="Hello";
mystring[] = "Hello";
5|Page
are not valid for arrays, like neither would be:
So remember: We can "assign" a multiple constant to an Array only at the moment of initializing
it. The reason will be more comprehensible when you know a bit more about pointers, since then
it will be clarified that an array is simply a constant pointer pointing to an allocated block of
memory. And because of this constant, the array itself cannot be assigned any value, but we can
assign values to each of the elements of the array.
At the moment of initializing an Array it is a special case, since it is not an assignation, although
the same equal sign (=) is used. Anyway, have always present the rule previously underlined.
Assigning values to strings
Therefore, since the lvalue of an assignation can only be an element of an array and not the entire
array, what would be valid is to assign a string of characters to an array of char using a method
like this:
mystring[0]='H';
mystring[1]='e';
mystring[2]='l';
mystring[3]='l';
mystring[4]='o';
mystring[5] = '\0';
But as you may think, this does not seem to be a very practical method. Generally for assigning
values to an array, and more specifically to a string of characters, a series of functions like strcpy
are used. strcpy (string copy) is defined in the cstring (string.h) library and can be called the
following way:
strcpy (string1, string2);
This does copy the content of string2 into string1. string2 can be either an array, a pointer, or a
constant string, so the following line would be a valid way to assign the constant string "Hello"
to mystring:
6|Page
For example:
int main ()
{
char MyStudent [20];
strcpy (MyStudent,"Abebe");
cout << MyStudent;
return 0;}
Look how we have needed to include <string.h> header in order to be able to use function strcpy.
Another frequently used method to assign values to an array is by using directly the input stream
(cin). In this case the value of the string is assigned by the user during program execution.
When cin is used with strings of characters it is usually used with its getline method that can be
called following this prototype:
where buffer is the address where to store the input (like an array, for example), length is the
maximum length of the buffer (the size of the array) and delimiter is the character used to
determine the end of the user input, which by default - if we do not include that parameter - will
be the newline character ('\n').
The following example repeats whatever you type on your keyboard. It is quite simple but serves
as example on how you can use cin.getline with strings:
7|Page
{
char mybuffer [100];
cout << "What's your name? ";
cin.getline (mybuffer,100);
cout << "Hello " << mybuffer << ".\n";
cout << "Which is your favourite team? ";
cin.getline (mybuffer,100);
cout << "I like " << mybuffer << " too.\n";
return 0;
}
Notice how in both calls to cin.getline we used the same string identifier (mybuffer). What the
program does in the second call is simply step on the previous content of buffer by the new one
that is introduced.
If you remember the section about communication through console, you will remember that we
used the extraction operator (>>) to receive data directly from the standard input. This method
can also be used instead of cin.getline with strings of characters. For example, in our program,
when we requested an input from the user we could have written:
This would work, but this method has the following limitations that cin.getline has not:
It can only receive single words (no complete sentences) since this method uses as
delimiter any occurrence of a blank character, including spaces, tabulators, newlines and
carriage returns.
It is not allowed to specify a size for the buffer. What makes your program unstable in
case that the user input is longer than the array that will host it.
For these reasons it is recommendable that whenever you require strings of characters coming
from cin you use cin.getline instead of cin >>.
Pointer in C++
8|Page
Pointers, References and Dynamic Memory Allocation are the most powerful features in C/C++
language, which allows programmers to directly manipulate memory to efficiently manage the
memory - the most critical and scarce resource in computer - for best performance. However,
"pointer" is also the most complex and difficult feature in C/C++ language.
Pointers are extremely powerful because they allow you to access addresses and manipulate their
contents. But they are also extremely complex to handle. Using them correctly, they could
greatly improve the efficiency and performance. On the other hand, using them incorrectly could
lead to many problems, from un-readable and un-maintainable codes, to infamous bugs such as
memory leaks and buffer overflow, which may expose your system to hacking. Many new
languages (such as Java and C#) remove pointer from their syntax to avoid the pitfalls of
pointers, by providing automatic memory management.
A computer memory location has an address and holds content. The address is a numerical
number (often expressed in hexadecimal), which is hard for programmers to use directly.
Typically, each address location holds 8-bit (i.e., 1-byte) of data. It is entirely up to the
programmer to interpret the meaning of the data, such as integer, real number, characters or
strings.
To ease the burden of programming using numerical address and programmer-interpreted data,
early programming languages (such as C) introduce the concept of variables. A variable is a
named location that can store a value of a particular type. Instead of numerical addresses, names
(or identifiers) are attached to certain addresses. Also, types (such as int, double, char) are
associated with the contents for ease of interpretation of data.
Each address location typically holds 8-bit (i.e., 1-byte) of data. A 4-byte int value occupies 4
memory locations. A 32-bit system typically uses 32-bit addresses. To store a 32-bit address, 4
memory locations are required.
The following diagram illustrates the relationship between computers' memory address and
content; and variable's name, type and value used by the programmers.
9|Page
A pointer variable (or pointer in short) is basically the same as the other variables, which can
store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a
char), a pointer stores a memory address.
Pointers must be declared before they can be used, just like a normal variable. The syntax of
declaring a pointer is to place a * in front of the name. A pointer is associated with a type (such
as int and double) too.
// or
type* ptr;
// or
For example,
int * iPtr; // Declare a pointer variable called iPtr pointing to an int (an int pointer)
Take note that you need to place a * in front of each pointer variable, in other words, * applies
only to the name that followed. The * in the declaration statement is not an operator, but
indicates that the name followed is a pointer variable. For example,
Naming Convention of Pointers: Include a "p" or "ptr" as prefix or suffix, e.g., iPtr, numberPtr,
pNumber, pStudent.
The address-of operator (&) operates on a variable, and returns the address of the variable. For
example, if number is an int variable, &number returns the address of the variable number.
You can use the address-of operator to get the address of a variable, and assign the address to a
pointer variable. For example,
int * pNumber; // Declare a pointer variable called pNumber pointing to an int (or int pointer)
pNumber = &number; // Assign the address of the variable number to pointer pNumber
int * pAnother = &number; // Declare another int pointer and init to address of the variable
number
As illustrated, the int variable number, starting at address 0x22ccec, contains an int value 88. The
expression &number returns the address of the variable number, which is 0x22ccec. This address
is then assigned to the pointer variable pNumber, as its initial value.
The indirection operator (or dereferencing operator) (*) operates on a pointer, and returns the
value stored in the address kept in the pointer variable. For example, if pNumber is an int
pointer, *pNumber returns the int value "pointed to" by pNumber.
For example,
11 | P a g e
int * pNumber = &number; // Declare and assign the address of variable number to pointer
pNumber (0x22ccec)
cout << pNumber<< endl; // Print the content of the pointer variable, which contain an address
(0x22ccec)
cout << *pNumber << endl; // Print the value "pointed to" by the pointer, which is an int (88)
*pNumber = 99; // Assign a value to where the pointer is pointed to, NOT to the pointer
variable
cout << *pNumber << endl; // Print the new value "pointed to" by the pointer (99)
cout << number << endl; // The value of variable number changes as well (99)
Take note that pNumber stores a memory address location, whereas *pNumber refers to the
value stored in the address kept in the pointer variable, or the value pointed to by the pointer.
The indirection operator (*) can be used in both the RHS (temp = *pNumber) and the LHS
(*pNumber = 99) of an assignment statement.
Take note that the symbol * has different meaning in a declaration statement and in an
expression. When it is used in a declaration (e.g., int * pNumber), it denotes that the name
followed is a pointer variable. Whereas when it is used in a expression (e.g., *pNumber = 99;
temp << *pNumber;), it refers to the value pointed to by the pointer variable
12 | P a g e