C++ Chapter 4
C++ Chapter 4
Chapter Four
4. Arrays and Strings
4.1. Introduction
Variables in a program have values associated with them. During program execution these
values are accessed by using the identifier associated with the variable in expressions etc. In
none of the programs written so far have very many variables been used to represent the
values that were required. Thus even though programs have been written that could handle
large lists of numbers it has not been necessary to use a separate identifier for each number in
the list. This is because in all these programs it has never been necessary to keep a note of each
number individually for later processing. For example in summing the numbers in a list only one
variable was used to hold the current entered number which was added to the accumulated
sum and was then overwritten by the next number entered. If that value were required again
later in the program there would be no way of accessing it because the value has now been
overwritten by the later input.
If only a few values were involved a different identifier could be declared for each variable, but
now a loop could not be used to enter the values. Using a loop and assuming that after a value
has been entered and used no further use will be made of it allows the following code to be
written. This code enters six numbers and outputs their sum:
sum = 0.0;
for (i = 0; i < 6; i++)
{
cin >> x;
sum += x;
}
This of course is easily extended to n values where n can be as large as required. However if it
was required to access the values later the above would not be suitable. It would be possible to
do it as follows by setting up six individual variables:
float a, b, c, d, e, f;
and then handling each value individually as follows:
sum = 0.0;
cin >> a; sum += a;
cin >> b; sum += b;
cin >> c; sum += c;
Tilksew Page 1 of 26
BH University Department of Computer Science
Tilksew Page 2 of 26
BH University Department of Computer Science
then if more records come to light it is easy to amend the program to cope with more values by
changing the value of NE. This works because the compiler knows the value of the constant NE
at compile time and can allocate an appropriate amount of space for the array. It would not
work if an ordinary variable was used for the size in the array declaration since at compile time
the compiler would not know a value for it.
4.3.2. Accessing Array Elements
Given the declaration above of a 100-element array the compiler reserves space for 100
consecutive floating point values and accesses these values using an index/subscript that takes
values from 0 to 99. The first element in an array in C++ always has the index 0, and if the array
has n elements the last element will have the index n-1.
An array element is accessed by writing the identifier of the array followed by the subscript in
square brackets. Thus to set the 15th element of the array above to 1.5 the following
assignment is used:
annual_temp[14] = 1.5;
Note that since the first element is at index 0, then the ith element is at index i-1. Hence in the
above the 15th element has index 14.
An array element can be used anywhere an identifier may be used. Here are some examples
assuming the following declarations:
const int NE = 100,
N = 50;
int i, j, count[N];
float annual_temp[NE];
float sum, av1, av2;
A value can be read into an array element directly, using cin
cin >> count[i];
The element can be increased by 5,
count[i] = count[i] + 5;
or, using the shorthand form of the assignment
count[i] += 5;
Array elements can form part of the condition for an if statement, or indeed, for any other
logical expression:
if (annual_temp[j] < 10.0)
cout << "It was cold this year " << endl;
Tilksew Page 3 of 26
BH University Department of Computer Science
for statements are the usual means of accessing every element in an array. Here, the first NE
elements of the array annual_temp are given values from the input stream cin.
for (i = 0; i < NE; i++)
cin >> annual_temp[i];
The following code finds the average temperature recorded in the first ten elements of the
array.
sum = 0.0;
for (i = 0; i <10; i++)
sum += annual_temp[i];
av1 = sum / 10;
Notice that it is good practice to use named constants, rather than literal numbers such as 10. If
the program is changed to take the average of the first 20 entries, then it all too easy to forget
to change a 10 to 20. If a const is used consistently, then changing its value will be all that is
necessary.
For example, the following example finds the average of the last k entries in the array. k could
either be a variable, or a declared constant. Observe that a change in the value of k will still
calculate the correct average (provided k<=NE).
sum = 0.0;
for (i = NE - k; i < NE; i++)
sum += annual_temp[i];
av2 = sum / k;
Important - C++ does not check that the subscript that is used to reference an array element
actually lies in the subscript range of the array. Thus C++ will allow the assignment of a value to
annual_temp[200], however the effect of this assignment is unpredictable. For example it could
lead to the program attempting to assign a value to a memory element that is outside the
program's allocated memory space. This would lead to the program being terminated by the
operating system. Alternatively it might actually access a memory location that is within the
allocated memory space of the program and assign a value to that location, changing the value
of the variable in your program which is actually associated with that memory location, or
overwriting the machine code of your program. Similarly reading a value from
annual_temp[200] might access a value that has not been set by the program or might be the
value of another variable. It is the programmer's responsibility to ensure that if an array is
declared with n elements then no attempt is made to reference any element with a subscript
Tilksew Page 4 of 26
BH University Department of Computer Science
outside the range 0 to n-1. Using an index, or subscript, that is out of range is called Subscript
Overflow. Subscript overflow is one of the commonest causes of erroneous results and can
frequently cause very strange and hard to spot errors in programs.
4.3.3. Initialization of arrays
The initialization of simple variables in their declaration has already been covered. An array can
be initialized in a similar manner. In this case the initial values are given as a list enclosed in
curly brackets. For example initializing an array to hold the first few prime numbers could be
written as follows:
int primes[] = {1, 2, 3, 5, 7, 11, 13};
Note that the array has not been given a size, the compiler will make it large enough to hold the
number of elements in the list. In this case primes would be allocated space for seven elements.
If the array is given a size then this size must be greater than or equal to the number of
elements in the initialization list. For example:
int primes[10] = {1, 2, 3, 5, 7};
would reserve space for a ten element array but would only initialize the first five elements.
Example Program: Printing Outliers in Data
The requirement specification for a program is:
A set of positive data values (200) are available. It is required to find the average value of these
values and to count the number of values that are more than 10% above the average value.
Since the data values are all positive a negative value can be used as a sentinel to signal the end
of data entry. Obviously this is a problem in which an array must be used since the values must
first be entered to find the average and then each value must be compared with this average.
Hence the use of an array to store the entered values for later re-use.
An initial algorithmic description is:
initialize.
enter elements into array and sum elements.
evaluate average.
scan array and count number greater than
10% above average.
output results.
This can be expanded to the complete algorithmic description:
set sum to zero.
set count to zero.
Tilksew Page 5 of 26
BH University Department of Computer Science
Tilksew Page 6 of 26
BH University Department of Computer Science
sum = sum + x;
indata[count] = x;
count = count + 1;
cin >> x;
}
// calculate average
average = sum/count;
// Output results
cout << "Number of values input is " << count;
cout << endl
<< "Number more than 10% above average is "
<< nogt10 << endl;
}
Since it was assumed in the specification that there would be less than 200 values the array size
is set at 200. In running the program less than 200 elements may be entered, if n elements
where n < 200 elements are entered then they will occupy the first n places in the array indata.
It is common to set an array size to a value that is the maximum we think will occur in practice,
though often not all this space will be used.
Example Program: Test of Random Numbers
The following program simulates the throwing of a dice by using a random number generator to
generate integers in the range 0 to 5. The user is asked to enter the number of trials and the
program outputs how many times each possible number occurred.
An array has been used to hold the six counts. This allows the program to increment the correct
count using one statement inside the loop rather than using a switch statement with six cases
to choose between variables if separate variables had been used for each count. Also it is easy
to change the number of sides on the dice by changing a constant. Because C++ arrays start at
subscript 0 the count for an i occurring on a throw is held in the i-1th element of this count
Tilksew Page 7 of 26
BH University Department of Computer Science
array. By changing the value of the constant die_sides the program could be used to simulate a
die_sides-sided die without any further change.
#include <iostream.h>
#include <stdlib.h> // time.h and stdlib.h required for
#include <time.h> // random number generation
void main()
{
const int die_sides = 6; // maxr-sided die
int count[die_sides]; // holds count of each
// possible value
int no_trials, // number of trials
roll, // random integer
i; // control variable
float sample; // random fraction 0 .. 1
Tilksew Page 8 of 26
BH University Department of Computer Science
Tilksew Page 9 of 26
BH University Department of Computer Science
Suppose that when the game begins. The king id located in the fourth position in the first row.
Counting from zero that position corresponds to board[0][3] in the two dimensional array,
assuming that the first subscript corresponds to the row, and the second to the column.
4.4.1. Initializing Multidimensional Arrays
To initialize a multidimensional arrays , you must assign the list of values to array elements in
order, with last array subscript changing while the first subscript while the first subscript holds
steady. Therefore, if the program has an array int theArray[5][3], the first three elements go int
theArray[0]; the next three into theArray[1]; and so forth.
The program initializes this array by writing
int theArray[5][3] ={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
for the sake of clarity, the program could group the initializations with braces, as shown below.
int theArray[5][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14,15} };
The compiler ignores the inner braces, which clarify how the numbers are distributed.
Each value should be separated by comma, regardless of whither inner braces are include. The
entire initialization must set must appear within braces, and it must end with a semicolon.
4.4.2. Omitting the Array Size
If a one-dimensional array is initialized, the size can be omitted as it can be found from the
number of initializing elements:
int x[] = { 1, 2, 3, 4} ;
This initialization creates an array of four elements.
Note however:
int x[][] = { {1,2}, {3,4} } ; // error is not allowed.
and must be written
int x[2][2] = { {1,2}, {3,4} } ;
Tilksew Page 10 of 26
BH University Department of Computer Science
Tilksew Page 11 of 26
BH University Department of Computer Science
then the field width will be expanded to fit the string exactly. If the string is to be left-justified
in the field then the setiosflags manipulator with the argument ios::left can be used.
4.5.2. String Input
When the input stream cin is used space characters, newline etc. are used as separators and
terminators. Thus when inputting numeric data cin skips over any leading spaces and
terminates reading a value when it finds a white-space character (space, tab, newline etc. ).
This same system is used for the input of strings, hence a string to be input cannot start with
leading spaces, also if it has a space character in the middle then input will be terminated on
that space character. The null character will be appended to the end of the string in the
character array by the stream functions. If the string s1 was initialized as in the previous
section, then the statement
cin >>s1;
would set the string s1 as follows when the string "first" is entered (without the double quotes)
|f|i|r|s|t|\0|e|\0|
Note that the last two elements are a relic of the initialization at declaration time. If the string
that is entered is longer than the space available for it in the character array then C++ will just
write over whatever space comes next in memory. This can cause some very strange errors
when some of your other variables reside in that space!
To read a string with several words in it using cin we have to call cin once for each word. For
example to read in a name in the form of a Christian name followed by a surname we might use
code as follows:
char christian[12], surname[12];
cout << "Enter name ";
cin >> christian;
cin >> surname;
cout << "The name entered was "
<< christian << " "
<< surname;
The name would just be typed by the user as, for example, Ian Aitchison and the output would
then be
The name entered was Ian Aitchison
Enter a string: Law is a bottomless pit.
You entered: Law
Where did the rest of the phrase go?
It turns the insertion operator >> consider a space to be a terminating character.
Tilksew Page 12 of 26
BH University Department of Computer Science
Thus it will read strings consisting of a single word, but anything typed after a space is thrown
away.
To read text containing blanks we use another function, cin::get().
#include<iostream.h>
void main()
{
const int max=80;
char str[max];
cout<<"\n Enter a string;";
cin.get(str,max); // max avoid buffer overflow
cout<<"\n You entered : "<<str;
}
Reading multiple lines
We have solved the problem of reading strings with embedded blanks, but what about strings
with multiple lines? It turns out that the cin::get() function can take a third argument to help
out in this situation.
This argument specifies the character that tells the function to stop reading. The default value
of this argument is the newline('\n')character, but if you call the function with some other
character for this argument, the default will be overridden by the specified character.
In the next example, we call the function with a dollar sign ('$') as the third argument
//reads multiple lines, terminates on '$' character
#include<iostream.h>
void main(){
const int max=80;
char str[max];
cout<<"\n Enter a string:\n";
cin.get(str, max, '$'); //terminates with $
cout<<\n You entered:\n"<<str; }
now you can type as many lines of input as you want. The function will continue to accept
characters until you enter the terminated character $ (or untill you exceed the size of the array.
Remember, you must still press Enter key after typing the '$' character .
4.5.3. Avoiding buffer over flow
The strings in the program invites the user to type in a string. What happens if the user enters a
string that is longer than the array used to hold it? There is no built-in mechanism in C++ to
keep a program from inserting array elements outside an array.
Tilksew Page 13 of 26
BH University Department of Computer Science
However, it is possible to tell the >> operator to limit the number of characters it places in an
array.
//avoids buffer overflow with cin.width
#include<iostream.h>
#include<iomanip.h> //for setw
void main(){
const int MAX=20;
char str[MAX];
cout<<"\n Enter a string: ";
cin>>setw(MAX)>>str;
cout<<"\n You entered :"<<str;
}
4.5.4. String constants
You can initialize a string to a constant value when you define it. Here's an example'
#include<iostream.h>
void main(){
char str[] = "Welcome to C++ programming language";
cout<<str;
}
if you tried to the string program with strings that contain more than one word , you may have
unpleasant surprise. Copying string the hard way
The best way to understand the true nature of strings is to deal with them character by
character
#include<iostream.h>
#include<string.h> //for strlen()
void main()
{
const int max=80;
char str1[]='' Oh, Captain, my Captain!"
our fearful trip is done";
char str2[max];
for(int i=0; i<strlen(str1);i++)
str2[i]=str1[1];
str2[i]='\0';
cout<<endl;
cout<<str2;
}
Tilksew Page 14 of 26
BH University Department of Computer Science
strcpy copies characters from the location specified by source to the location specified by
destination. It stops copying characters after it copies the terminating null character.
o The return value is the value of the destination parameter.
You must make sure that the destination string is large enough to hold all of the characters in
the source string (including the terminating null character).
Example:
#include <iostream.h>
#include <string.h>
void main(){
char me[20] = "David";
cout << me << endl;
strcpy(me, "YouAreNotMe");
cout << me << endl ;
return;
}
There is also another function strncpy, is like strcpy, except that it copies only a specified
number of characters.
strncpy(destination, source, int n);
Tilksew Page 15 of 26
BH University Department of Computer Science
}
4.5.6. Concatenating strings
In C++ the + operator cannot normally be used to concatenate string, as it can in some
languages such as BASIC; that is you can't say
str3 = str1 + str2;
You can use strcat() or strncat
The function strcat concatenates (appends) one string to the end of another string.
strcat(destination, source);
o The first character of the source string is copied to the location of the terminating null
character of the destination string.
o The destination string must have enough space to hold both strings and a terminating null
character.
Example:
#include <iostream.h>
#include <string.h>
void main() {
char str1[30];
strcpy(str1, "abc");
cout << str1 << endl;
strcat(str1, "def");
cout << str1 << endl;
The function strncat is like strcat except that it copies only a specified number of characters.
strncat(destination, source, int n);
It may not copy the terminating null character.
Example:
#include <iostream.h>
#include <string.h>
void main() {
char str1[30];
strcpy(str1, "abc");
cout << str1 << endl;
strncat(str1, "def", 2);
str1[5] = '\0';
Tilksew Page 16 of 26
BH University Department of Computer Science
strncmp does not compare characters after a terminating null character has been found in one
of the strings.
Example:
#include <iostream.h>
#include <string.h>
void main()
{
cout << strncmp("abc", "def", 2) << endl;
cout << strncmp("abc", "abcdef", 3) << endl;
cout << strncmp("abc", "abcdef", 2) << endl;
cout << strncmp("abc", "abcdef", 5) << endl;
cout << strncmp("abc", "abcdef", 20) << endl;
}
Tilksew Page 17 of 26
BH University Department of Computer Science
4.6. Pointers
A pointer is simply the address of a memory location and provides an indirect way of accessing
data in memory. A pointer variable is defined to ‘point to’ data of a specific type. For example:
int *ptr1; // pointer to an int
char *ptr2; // pointer to a char
The value of a pointer variable is the address to which it points. For example, given the
definitions
int num;
we can write:
ptr1 = #
The symbol & is the address operator; it takes a variable as argument and returns the memory
address of that variable. The effect of the above assignment is that the address of num is
assigned to ptr1. Therefore, we say that ptr1 points to num. Figure 5. illustrates this
diagrammatically.
ptr1 num
Figure: A simple integer pointer.
Given that ptr1 points to num, the expression
*ptr1
dereferences ptr1 to get to what it points to, and is therefore equivalent to num. The symbol * is
the dereference operator; it takes a pointer as argument and returns the contents of the
location to which it points.
In general, the type of a pointer must match the type of the data it is set to point to. A pointer
of type void*, however, will match any type. This is useful for defining pointers which may point
to data of different types, or whose type is originally unknown. A pointer may be cast (type
converted) to another type. For example,
ptr2 = (char*) ptr1;
Tilksew Page 18 of 26
BH University Department of Computer Science
dynamically allocating memory blocks during program execution. As a result, it is also called
dynamic memory. Similarly, the program stack is also called static memory.
Two operators are used for allocating and deallocating memory blocks on the heap. The new
operator takes a type as argument and allocated a memory block for an object of that type. It
returns a pointer to the allocated block. For example,
int *ptr = new int;
char *str = new char[10];
allocate, respectively, a block for storing a single integer and a block large enough for storing an
array of 10 characters.
Memory allocated from the heap does not obey the same scope rules as normal
variables. For example, in
void Foo (void)
{
char *str = new char[10];
//...
}
when Foo returns, the local variable str is destroyed, but the memory block pointed
to by str is not. The latter remains allocated until explicitly released by the
programmer.
The delete operator is used for releasing memory blocks allocated by new. It takes a
pointer as argument and releases the memory block to which it points. For example:
Tilksew Page 19 of 26
BH University Department of Computer Science
Annotation (analysis)
1 This is the standard string header file which declares a variety of functions for
manipulating strings.
4 The strlen function (declared in string.h) counts the characters in its string
argument up to (but excluding) the final null character. Because the null
character is not included in the count, we add 1 to the total and allocate an
array of characters of that size.
5 The strcpy function (declared in string.h) copies its second argument to its first,
character by character, including the final null character.
Because of the limited memory resources, there is always the possibility that
dynamic memory may be exhausted during program execution, especially when
many large blocks are allocated and none released. Should new be unable to
allocate a block of the requested size, it will return 0 instead. It is the responsibility
of the programmer to deal with such possibilities.
str++ advances str by one char (i.e., one byte) so that it points to the second character
of "HELLO", whereas ptr++ advances ptr by one int (i.e., four bytes) so that it points to
the second element of nums. Figure 5.1 illustrates this diagrammatically.
str ptr
str++ ptr++
It follows, therefore, that the elements of "HELLO" can be referred to as *str, *(str
+ 1), *(str + 2), etc. Similarly, the elements of nums can be referred to as *ptr, *(ptr + 1),
*(ptr + 2), and *(ptr + 3).
Another form of pointer arithmetic allowed in C++ involves subtracting two
pointers of the same type. For example:
int *ptr1 = &nums[1];
Tilksew Page 20 of 26
BH University Department of Computer Science
Listing 5.2
1 void CopyString (char *dest, char *src)
2 {
3 while (*dest++ = *src++)
4 ;
5 }
Annotation
3 The condition of this loop assigns the contents of src to the contents of dest and
then increments both pointers. This condition becomes 0 when the final null
character of src is copied to dest.
In turns out that an array variable (such as nums) is itself the address of the first
element of the array it represents. Hence the elements of nums can also be referred
to using pointer arithmetic on nums, that is, nums[i] is equivalent to *(nums + i). The
difference between nums and ptr is that nums is a constant, so it cannot be made to
point to anything else, whereas ptr is a variable and can be made to point to any
other integer.
Listing 5.3 shows how the HighestTemp function (shown earlier in Listing 5. can
be improved using pointer arithmetic.
Listing 5.3
1 int HighestTemp (const int *temp, const int rows, const int columns)
2 {
3 int highest = 0;
4 for (register i = 0; i < rows; ++i)
5 for (register j = 0; j < columns; ++j)
6 if (*(temp + i * columns + j) > highest)
7 highest = *(temp + i * columns + j);
8 return highest;
9 }
Annotation
1 Instead of passing an array to the function, we pass an int pointer and two
additional parameters which specify the dimensions of the array. In this way,
the function is not restricted to a specific array size.
6 The expression *(temp + i * columns + j) is equivalent to temp[i][j] in the previous
version of this function.
Listing 5.4
Tilksew Page 21 of 26
BH University Department of Computer Science
1 int HighestTemp (const int *temp, const int rows, const int columns)
2 {
3 int highest = 0;
4 for (register i = 0; i < rows * columns; ++i)
5 if (*(temp + i) > highest)
6 highest = *(temp + i);
7 return highest;
8 }
4.6.3. Function Pointers
It is possible to take the address of a function and store it in a function pointer. The
pointer can then be used to indirectly call the function. For example,
int (*Compare)(const char*, const char*);
defines a function pointer named Compare which can hold the address of any
function that takes two constant character pointers as arguments and returns an
integer. The string comparison library function strcmp, for example, is such.
Therefore:
Compare = &strcmp; // Compare points to strcmp function
When a function address is assigned to a function pointer, the two types must
match. The above definition is valid because strcmp has a matching function
prototype:
int strcmp(const char*, const char*);
Given the above definition of Compare, strcmp can be either called directly, or
indirectly via Compare. The following three calls are equivalent:
strcmp("Tom", "Tim"); // direct call
(*Compare)("Tom", "Tim"); // indirect call
Compare("Tom", "Tim"); // indirect call (abbreviated)
Tilksew Page 22 of 26
BH University Department of Computer Science
Listing 5.5
1 int BinSearch (char *item, char *table[], int n,
2 int (*Compare)(const char*, const char*))
3 {
4 int bot = 0;
5 int top = n - 1;
6 int mid, cmp;
7 while (bot <= top) {
8 mid = (bot + top) / 2;
9 if ((cmp = Compare(item,table[mid])) == 0)
10 return mid; // return item index
11 else if (cmp < 0)
12 top = mid - 1; // restrict search to lower half
13 else
14 bot = mid + 1; // restrict search to upper half
15 }
16 return -1; // not found
17 }
Annotation
1 Binary search is a well-known algorithm for searching through a sorted list of
items. The search list is denoted by table which is an array of strings of
dimension n. The search item is denoted by item.
2 Compare is the function pointer to be used for comparing item against the array
elements.
7 Each time round this loop, the search span is reduced by half. This is repeated
until the two ends of the search span (denoted by bot and top) collide, or until a
match is found.
9 The item is compared against the middle item of the array.
10 If item matches the middle item, the latter’s index is returned.
11 If item is less than the middle item, then the search is restricted to the lower
half of the array.
14 If item is greater than the middle item, then the search is restricted to the upper
half of the array.
16 Returns -1 to indicate that there was no matching item.
The following example shows how BinSearch may be called with strcmp passed as
the comparison function:
char *cities[] = {"Boston", "London", "Sydney", "Tokyo"};
cout << BinSearch("Sydney", cities, 4, strcmp) << '\n';
Tilksew Page 23 of 26
BH University Department of Computer Science
4.6.4. References
A reference introduces an alias for an object. The notation for defining references is
similar to that of pointers, except that & is used instead of *. For example,
double num1 = 3.14;
double &num2 = num1; // num is a reference to num1
defines num2 as a reference to num1. After this definition num1 and num2 both refer
to the same object, as if they were the same variable. It should be emphasized that
a reference does not create a copy of an object, but merely a symbolic alias for it.
Hence, after
num1 = 0.16;
You can also initialize a reference to a constant. In this case a copy of the
constant is made (after any necessary type conversion) and the reference is set to
refer to the copy.
int &n = 1; // n refers to a copy of 1
The reason that n becomes a reference to a copy of 1 rather than 1 itself is safety.
Consider what could happen if this were not the case.
int &x = 1;
++x;
int y = x + 1;
The 1 in the first and the 1 in the third line are likely to be the same object (most
compilers do constant optimization and allocate both 1’s in the same memory
location). So although we expect y to be 3, it could turn out to be 4. However, by
forcing x to be a copy of 1, the compiler guarantees that the object denoted by x will
be different from both 1’s.
The most common use of references is for function parameters. Reference
parameters facilitates the pass-by-reference style of arguments, as opposed to the
pass-by-value style which we have used so far. To observe the differences, consider
the three swap functions in Listing 5.6.
Tilksew Page 24 of 26
BH University Department of Computer Science
Listing 5.6
1 void Swap1 (int x, int y) // pass-by-value (objects)
2 {
3 int temp = x;
4 x = y;
5 y = temp;
6 }
7 void Swap2 (int *x, int *y) // pass-by-value (pointers)
8 {
9 int temp = *x;
10 *x = *y;
11 *y = temp;
12 }
13 void Swap3 (int &x, int &y) // pass-by-reference
14 {
15 int temp = x;
16 x = y;
17 y = temp;
18 }
Annotation
1 Although Swap1 swaps x and y, this has no effect on the arguments passed to
the function, because Swap1 receives a copy of the arguments. What happens
to the copy does not affect the original.
7 Swap2 overcomes the problem of Swap1 by using pointer parameters instead. By
dereferencing the pointers, Swap2 gets to the original values and swaps them.
13 Swap3 overcomes the problem of Swap1 by using reference parameters instead.
The parameters become aliases for the arguments passed to the function and
therefore swap them as intended.
Swap3 has the added advantage that its call syntax is the same as Swap1 and
involves no addressing or dereferencing. The following main function illustrates the
differences:
Tilksew Page 25 of 26
BH University Department of Computer Science
The effect of these definitions is that String becomes an alias for char*, Name
becomes an alias for an array of 12 chars, and uint becomes an alias for unsigned int.
Therefore:
String str; // is the same as: char *str;
Name name; // is the same as: char name[12];
uint n; // is the same as: unsigned int n;
The typedef introduces Compare as a new type name for any function with the given
prototype. This makes BinSearch’s signature arguably simpler.
Tilksew Page 26 of 26