Page 1
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 1/51
Contents
FOUR Arrays pointers and Generic Code 123
4.1 Array Concepts and Declarations 123
4.2 Pointers and Address Arithmetic 125
4.3 Two-Dimensional Arrays 133
4.4 A Matrix Class 135
4.5 A Class of Polynomials 138
4.6 Array Objects: vector 141
4.7 Sorting Text Lines with Objects 143
4.8 Pointers and Function Calls 151
4.9 Arrays, Pointers, and References 154
4.10 Multiple Indirections 154
4.11 Generic Programs 156
4.12 A Generic Sorting program 162
4.13 Pointers and Dynamically Allocated storage 165
4.14 Summary 168
Exercises 169
Page 2
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 2/51
u
C H A PT ER F O UR I
Arrays . Pointers .and Generic C ode
The array is one of the most usef ul data structures in programming. Ar
are often encapsulated in classes as internal mechanisms. A single array
group many related data items of the same type for easy processing. Rand
access to stored elements is most efficientthrough array ind e xing. Arrays are u
ally one-dimensional (with one index). Multidimensional arrays are also
sible. A matrix multiplication example illustrates the use of two-dimensio
arrays.
The length of an array is static, or fixed at compile time. The vector c
in the Standard Library is a versatile container class that work s like an a
with dynamically changing length. The vector class also supplies many us
member functions, including efficient random access to stored elements.
A pointer is a value that point s to the memory location (address) of ano
value. Through such ind ir ection, pointers provide flexibility in organizing accessing data stored in a program. Arrays and pointers have a very intim
relationship, and pointers are made easier through array concepts. Poi
arithmetic is presented carefully and clearly. Pointer and ref erence parame
for functions, multiple indirection, and pointer arrays are also discussed.
A set of well-chosen applications demonstrates how arrays and poin
are used effectively in practice. Sorting text lines with objects provides a c
plete example that combines many of the constructs and techniques presen
Pointers to functions, f ormal functional parameters, and the void *
are explained individually and then combined to write gener ic pr ogr ams , wh
are programs that can be used on a multitude of data types.
The array is the simplest data structure beyond the basic types such as c
int, and float. In earlier chapters, we have already seen some use of arr
In general, an array is a section of consecutive memor y cells, each large eno
Page 3
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 3/51
to hold a data element of the same predetermined type. Each cell in an array
is also referred to as an ar ray entry or array element . The declaration
establishes str as a one-dimensional array of ten entries, str[O], str[l], up
to str [9], each of type char. An array can be initialized when declared (Sec-
tion 1.12). The initializers enclosed in braces ({})must be constant expressions.
Here is an array of two objects with initializers:
Fraction f rac_arr[) = { Fraction(1,2),
Fraction(3,4) };
When an array of objects is declared, the no-args constructor is always used first
to initialize each array element. Declaring an array involving objects whose
class has no default constructor is an error.For example, the preceding frac_arr
cannot be declared if Fraction has no default constructor.
The ind e x notation str [n) refers to the (n + l)th entry of str. In general, if
there are k entries, the index goes from a to k - 1. The index notation is used
to store and retrieve values in an array:
str[O)='A' ;
cout.put(str[O));
str[l)='B' ;
cout.put(str[l));
In other words, each array entry is used just like a variable of the declared
type. The advantage is that array entries are indexed and can therefore be used
effectively in loops. Although each array entry is like a variable, the array name
is a constant representing the address (memory location) of the first entry ofthearray. Thus, str is a constant whose value is the location of str (0). Because the
array name is a constant, its value cannot be changed. Hence, an array name
cannot be used on the left-hand side of an assignment or with a decrement or
increment operator such as str++.
As an address, an array name can be assigned to a pointer variable of the
appropriate type. Thus,
char *s;
s = str;s [0] = IZ' ;
is a roundabout way to assign the character 'Z ' to str [0).
An array name can also be used in a function call as an argument. At the
time of the call, the value of the array name (the address of the first entry of the
array) is passed to the formal parameter in the called function. Array formal
Page 4
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 4/51
parameters are local variables and are usually used just like pointer varia
The function
is an example.
Up to this point, we have used indexing with arrays and pointers.index notation is easy to read and understand, but pointers can also be ma
ulated directly, as explained in Section 4.2.
A pointer variable is a variable whose value is the address of a memory loc
where a specific type of data is stored. When a pointer variable is declared
data type it points to is specified. The notations
i nt * a, * b ;
c h ar * r, * s ;
A c c o u n t * u ;
F r a c t i o n * f ;
declare a and b as integer pointer variables and r and s as character po
variables. The pointers u and f can hold addresses for an A c c o u n t object a
F r a c t i o n object, respectively. Figure 4.1 shows a regular variable p at memlocation 1200and a pointer variable qat location 1204without an initial v
A pointer declaration merely creates the pointer variable; it neither initia
the pointer variable nor allocates memory space for the variable to poin
Therefor e , be for e a point er va riable is used , it must be assigned the address o f an a
a variable, an object, or some dynamically allocat ed s pa ce . Figure 4.2shows qge
the address of p. Therefore, the sequence
i nt * p tc a ;
i n t m [ ] = { 1 , 2 , 3 , 4 } ;
p t r _ a = m ;
II m i s a n i n t e g e r a r r a y
I I p o i n t e r p tr _ a a ss i g ne d a dd re ss o f
Page 5
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 5/51
q
1 2 00
II entries of m referenced through ptr_a
ptr_a[3]= ptr_a[0]t5*ptr_a[1];
results in m [3] being 11. Since ptr3 is a pointer variable of type int, it can
assigned the address of an integer array m . For a Vector2Dpointer, the sa
guidelines apply:
Vector2D *v = new Vector2D[2] ;
v[O] = Vector2D(0.0, 1.0);v[l] = Vector2D(1.0, O.O};
Two unary operators are important in dealing with pointers: &,the address
operator, and *, the value-of operator. The address-of operator &produce
pointer to, or an address of, an lvalue: a variable or an array entry in memo
The statement
assigns to ap the address of the int array entry m [3] and causes ap to po in
m [3] . Similarly,
assigns the address of the object v [1] to vp. The address-of operator &
be applied only to data stored in memory and does not work with consta
register variables, or expressions such as (a + b).
Taking the address of a ref erence gives the address of the variable reenced. For example,
Cirbuf b(256}i
Cirbuf & cbuf = b;
Cirbuf* b-ptr = &cbuf ;
II circular buff er ob ject
II cbuf is ref erence to b
I I b-ptr = = address of b
Note that Cirbuf & is a reference type declaration and has not hing to do w
the address-of operator &.
Page 6
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 6/51
The value-of operator * is used to access a data item through a poin
The * can be used on a pointer variable, a pointer constant, or any expres
that produces a valid pointer value. After int *ptr3 = &ai, the notation
stands for the variable a and behaves exactly the same. Thus, *ptr3 hasvalue of a, and
is the same as saying a=5because it stores 5 at the address where a store
value. Note that the value of the pointer variable ptr3 itselfis not change
this assignment. In general, if ptr is a pointer of a certain type, then *ptr
be used as a variable of that type. The following code further illustrates
concept:
*ptr_a = i - 3
* m += 2
i = 5 * *ptr_a
( i >= *ptr_a )
++*ptr_a
(*m) --
II ptr_a is a pointer variable, i intege
II m is an int array
II multiplication
II relational operation
II or (*ptr_a)++, increment *ptr_a
II or --*m, decrement *m
The unary operators * and &have the same precedence as unary arithm
operators and have higher precedence than binary arithmetic and relati
operators. The parentheses are necessary in the last example because un
operators such as *,H, and -- associate right to left. Hence,
*ptr_a-- and *(ptr_a--)
are equivalent and would decrement the pointer variable ptr_a rather than
integer *ptr3.
Another general observation that canbe made of the *operator is that
is always equivalent topt r [0]. In fact, the compiler automatically converts
latter notation to the former. This is another reason why pointers are clo
related to arrays.
For an integer pointer variable ptr_a, it is clear what *ptca means. But w
is &ptr3? By definition, it is the address of ptr3. In other words, &ptr3
pointer to an integer pointer. Thus, the artificial sequence
int k, *ptr_a, **ptr_bi
ptr_b = &ptr3i
II ptr_b is a pointer to an int pointer
II ptr_b points to ptr_a
Page 7
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 7/51
ptr_a = &k;
**ptr_b = 1 5;
II ptr_a points to k (same as *ptr_b =II k gets 15
results in the variable k being assigned the value 15,as illustrated in Figure
Here is how it works:
1. Since ptr_b points to ptr_a, *ptr_b is ptr_a.
2. Since ptr3 points to k, **ptr_b is k.
3. Thus, **ptr_b = 15 is the same as k = 15.
The same reasoning can be applied to unravel multiple indirections
tion 4.10).
Address arithmetic calculates memory addresses using pointers. Thus,
also known as pointer ar ithmetic. A pointer is an integer byte count identif
a memory location so many bytes away from a certain reference address,
as the beginning of a program. For instance, 15084points to byte 15084f
the reference location. A pointer gives the beginning of a data cell , which
take 1 or more bytes, depending on the type of data stored there. The e
number of bytes for each data type is implementation dependent. On 3
computers, a char usually takes 1byte and an int 4 bytes.
In practice, a pointer is often used to access a sequence of data cells st
in consecutive memory locations rather than just a single cell. Toget from
such data cell to the next, you can use several convenient address arithm
operations:
• Pointer + integer, resulting in a pointer.
• Pointer - integer, giving another pointer.
• Pointer - pointer, getting an integer.
A discussion of each of these operations follows.
Pointer + Integer Adding an integer quantity to a pointer is not as m
terious as it may seem. In fact, we have been doing it implicitly all along.
Page 8
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 8/51
familiar array notation b [3] retrieves the desired data by calculating
dress based on the information that it is the third item after the cellat b,n
b [0]. With e xp licit address arithmetic , the same address can be computed
The result of this address addition is a pointer to b [3], as shown in Figu
Note that this is not adding 3; rather, it is adding three times the size
data cell to the address represented by b.
Thus, if b is an i n t pointer and b is 1 5 0 8 4 , the pointer b+3 has
1 5 0 8 4 + 1 2 =1 5 0 9 6 , assuming that i n t takes 4 bytes. But if b is a c h a r p
b+3 becomes 1 5 0 8 4 + 3 = 1 5 0 8 7 . When an address arithmetic expressio
as b+3 is encountered by the compiler, it takes the size of the data ce
account and produces the appropriate code. This arrangement is conv
for programming and makes the program independent of the data typon different computers.
As a result, the general rule holds: If p t r is a pointer and n an intege
is the pointer for the nth data cell from the one pointed to by p t r . A
expression
is the same as p t r [ n ] , where p t r can be a pointer variable or an array n
To further illustrate pointer usage, let's consider a pointer version
library function strcmp, which returns an integer value greater than, eq
or less than zero if the C-style string r is greater than, equal to, or less th
string s, respectively:
i nt s t r c m p ( c o n s t c h a r * r , c a n s t c h a r * s )
{ w h i l e ( * r = = * s )
{ i f ( * r = = ' \ 0 ' ) r e t u r n O J II s t r i n g s a r e e qu al
II a d v a n c e p o i n t e r s
b[O]
t
b[l]
t
b[2]
t
b[3]
t
Page 9
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 9/51
The definition of strcmp depends on the fact that the string terminato
zero-valued character.
As another example, consider a pointer implementation of the l
function strcpy, which makes a copy of its second argument into th
argument:
char *strcpy(char *s, const char *cs)
{ char *tmp = Si
while (*cs != ' \ O') *(tmp++) = *(cs++); II copy next charac
*tmp = ' \ 0' i
return Si
The pointer variable tmpis first declared and initialized to s. Next, the
loop copies each character on the string cs until' \ 0' is encountered. F
the terminator ' \ 0' is copied, and the pointer s is returned. The variable
technically unnecessary because s can serve as a r eturn paramet er (Sectio
A common source of error in copying by passing pointers is insuff
space to receive the data being copied. In this example, s is assumed to
to the beginning of a reserved space large enough to hold the entire string
minimum number of bytes needed is
strlen(cs) + 1
where the ' \ 0I
terminator occupies the final byte. In this case, it is the resibility of the calling function to ensure that enough space has been prov
If this is undesirable, the copying function may dynamically allocate sp
in the function dstrcpy (dynamic string copy):
char{
*dstrcpy(const char *cs}
char *s, *tmp;
unsigned size = strlen(cs)+l;
tmp = s = new(char[size]);
while (*cs != ' \0 '1 *(tmp++)=
*tmp = ' \0';
return s;
II or size t size
II allocate space
*(cs++); I I copy next chara
Note that the pointer returned by dstrcpy can later be freed with delete.
The Standard c++ string class (Section 6.3) provides many opera
that are easier and safer to use than the preceding functions.
Pointer - Integer Subtracting an integer from a pointer is the inve
adding an integer. An example is contained in a pointer implementation
Page 10
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 10/51
function match, which compares a string runwith the pref ix of a name-v
string nv:
II Both runand nv are strings:
II runis the target name to f ind, nv is in the form name=value
II If the names match, value is returned, else NULL is returned
char *match(const char *run, canst char *nv)
while ( *run== *nv++ )
if ( *run++== '=') return nv; II field delimiter
if (*run== ' \ 0' & & *(nv-l) == '=')
return nv;
return NULL;
Immediately after the while loop, the last step in determining a match
pair the terminator of runwith the f ield delimiter =, one character before
The pointer subtraction *(nv-l) gives the exact character needed.
For functions, such as match, that return pointers, it is conventional t
turn an invalid pointer NULL when the computation f ails. The symbolic cons
NULL is defined as zero in the header <stddef. h>.But if you include <iostre
or other frequent headers, you already have NULL defined. Although NULL
be assigned to any pointer variable, deref erencing it with * is a run-time e
which can crash the program.
With pointer subtraction, we have the alternative of going back ward sequence of data cells. For instance, a loop may go from the end of an a
to the beginning. This flexibility and power do not come without danger
careful not to f all o f f the end of the data cells by going beyond the proper ra
P ointer - P ointer It is also valid to subtract one pointer f rom anothe
p and qare pointers to entries of the same array, then
is an integer n that is the distance between cells p and q. In other words,
n is q. Note that n can be positive, negative, or zero. Here is a pointer-ba
version of strlen that uses this feature:
int strlen(const char *s} II computes length of string s
canst char *t = s;
while( *t++ != ' \ 0' ) {} II go to end of string
return t-s-l; II length of string without terminat
Page 11
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 11/51
In this version of strlen, the while loop, with an empty body, incremen
until it reaches the end of the string. Then, the return statement computes
correct length of s via pointer subtraction.
Actually, the pointer variable t is incremented to one character beyo
the terminating I \ a I• So potentially, tnow points to some address that m
contain another type of data or may even be outside of the address spacthe program. But this is only a problem if access is attempted - say, with
In this section, valid pointer operations are summarized for easy reference.
material here also contains some details not previously mentioned, as wel
topics yet to come in this chapter.
• Cr eation: The initial value of a pointer has three possible sources: aconstant pointer such as an array name, an address obtained with th
operator, or a value returned by a dynamic memory allocation
operation.
• Assignment: Pointers of the same type can be assigned. Pointers of
different types can be assigned only with an explicit cast (Section 3.1
However, a void * variable can be assigned a pointer of any type
without explicit casting. An array name is a constant pointer and
cannot be used on the left-hand side of an assignment. The NULL poin
(usually zero) can be assigned as a pointer value.• p ± int eger : Adding or subtracting an integer from a pointer also
includes the operations pH, p--, P += 2, and so on. Such expression
are valid as long as the resulting pointer is within the range of the sa
array. A pointer is also allowed to go one step beyond the high end o
an array. In other words, if ppoints to the last entry of an array, the
pointer p+l is valid as long as no attempt is made to access the
nonexistent entry that it points to. Although most compilers do not
check whether a pointer falls outside its range, it is good practice to
make sure that it stays within the allowed bounds.
• Point er sub t r act ion: Pointers of the same type can be subtracted, yield
an integer that is positive, negative, or zero. In practice, only pointers
entries of the same array are subtracted.
• C omparison: Pointers to entries of the same array can be compared w
= = , <, >, and so on. Any pointer can be checked for equality with the
NULL pointer. A function returning a pointer usually returns NULL as
indication of error or failure. The calling function must compare the
returned pointer with NULL to detect such an error.
Page 12
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 12/51
• Indir ection: For a pointer p t r of a certain type, * p t r becomes a vari
of that type and therefore can be used in expressions and on the
left-hand side of an assignment.
• Indexing: A pointer p, whether an array name or a pointer variable
be used with an index subscript as in p [i] ,where i is a positive o
negative integer. The notation is converted by the compiler to * (p
Again, it is the programmer's responsibility to make sure that the
indexing stays within the bounds of the array.
Up to this point, all of the arrays we have seen use a single index or sub
Such arrays are one-dimensional. It is possible to have arrays with more
one subscript. For example,
declares a to be a two-dimensional array with the first subscript going fro
1 and the second ranging from 0 to 3. In other words, the array can be th
of as a rectangular grid of two rows and four columns (Figure 4.5). The
memory organization of a two-dimensional array is still linear: A total o
entries are allocated in consecutive memory cells (Figure 4.6). The array e
are stored by rows, with the first row followed by the second row and
Using pointer arithmetic, the organization by rows also means that the ad&a[i] [j] is given by
where 4 is the number of columns of a. Thus, it is possible to access a
using the alternative notation
int *p = &a[O] [0] i
* ( p + i * 4 + j )
or equivalently
p [ i * 4 + j]
a [0] [0]
a [1] [0]
a[O] [1]
a [1] [1]
a [0] [2]
a [1] [2]
a [0] [3]
a [1] [3]
Page 13
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 13/51
int a[][4]= { {O,l,2,3}, {4,5,6,7} };
Note that the range of the last subscript must be given explicitly.The initialize
is a list of sublists for the rows. No sublist may contain more elements tha
the range specified in the declaration. On the other hand, it is always possib
to initialize less than the full range for any row. Some sublists may even b
empty ({}).
One natural question to ask at this point is, Why is the syntax
used in other programming languages? The answer is that a two-dimensiona
array is really just a one-dimensional array of elements that are themselve
one-dimensional arrays. Thus, a [i] [j] literally means (a [i] ) [j], and a [i
is a constant pointer, of type int *, pointing to the i +first row of the two
dimensional array a. The following test program further illustrates many co
cepts related to pointers and the two-dimensional array:
int main()
const int RANGE=4;int a[] [RANGE]= { {O,1,2,3}, {4,5}, {8,9,10,ll} };
int *p &a[O][0];
int *q a[O];
int *r a[l];
int *s a[2];
std: :cout « *(p+RANGE+1)« std: :endl;
std: :cout « *(q+2*RANGE+2)« std: :endl;
std:std:: :cout « *r « std::endl;std: :cout « *(r-2) « std: :endl;
std: :cout « s[3] « std: :endl;
return 0;
II p and q are the sam
II pointer to 2nd row
II pointer to 3rd row
I I a[l] [1]
I I a[2] [2]
/ / a[l] [0]
I I a[O] [2]
//a[2][3]
The variable a is created as a 3 x 4 two-dimensional array of consecutiv
integers. The second row is partially initialized. The pointers q, r, and s poin
Page 14
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 14/51
to the first, second, and third row of a, respectively. A variety of notations h
been used to access cells of a to reinforce your understanding of the t
dimensional array representation, as well as pointer arithmetic.
Having a basic understanding of arrays and pointers, we are now re
to apply them.
Now let's consider writing a simplified Matrix class. The example illustr
the practical use of double arrays in numeric computing.
I I I I I I I Matrix.h
#include <iostream>
class Matrix
public:
Matrix() { mat = N U L L; }
Matrix(int r, int c);
Matrix(double* m, int r, int c);
-Matrix() { delete mat; }
double getElement(int i, int j) const;
void setElement(int i, int j, double e);
int rows() const { return nr; }
int cols() const { return nc; }
void times (const Matrix& b, Matrix& ans) const;void display() const;
private:
double rowTimesCol(int i, double* b, int j, int bc) const;
void setUp(int r, int c);
double* mat;
int nr, nc;
I I (I)
I I (2)
II the matrix
II rows and cols
A Matrix object has nr rows and nc columns of double elements sto
at mat in row-major format (one row after another). A Matrix object caninitialized with just dimensions (line 1)or a row-ma jor array of double (lin
These are implemented as follows:
I I I I I I I Matrix.C
#include <math.h>
#include "Matrix.h"
Page 15
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 15/51
v o i d M a t r i x : : s e t U p ( i n t r , i n t c )
{ i f ( r > 0 && c > 0 )
{ n r = r i n c = C i
m at = n e w d o u b le [ r * C ] i
}
e l s e
{ m a t N U L L i nr= nc= O ;
M a t r i x : : M a t r i x (d o u b le * m , i n t r , i nt c )
{ s e t U p ( r , c ) ;
i f ( m a t ! = N UL L )
f o r ( i n t i = O ; i < r * c ; i + + ) m a t [ i ]
F u n c t i o n s f o r r e t r i e v i n g d i m e n s i o n s a r e s i m p l e a n d g i v e n i n t h e h e a d e r f
F u n c t i o n s t o g e t / s e t e n t r i e s c h e c k s u b s c r i p t r a n g e s . T h e i l l e g a ld o u b l e s y m b
H U G E 3 A L ( f r o m < m at h . h » i s r e t u r n e d b y g e t E le m en t f o r i l l e g a li n d i c e s.
d o u b l e M a t r i x : : g e t E l e m e n t ( i n t i , i n t j } c o n s t
{ i f ( O < = i & & i < n r & & O < = j & & j < n c )
r e t u r n m a t [ i * n c + j ] ;
e ls e r et ur n H U G E _ V A L ; II i l l e g a l v a l u e
v o i d M a t r i x : : s e t E le m e n t ( i n t i , i n t j , d o u b l e e )
{ i f ( O <= i & & i < n r & & O < = j & & j < n c )
m at [ i * nc + j ] = e ;
T he m em b e r f u n c t i o n t i m e s m u l t i p l i e s t w o m a t r ic e s . T h e p r o du c t o f a n r
m at r i x A b y a n s x t m at r i x B is an r x t m a t r i x C. ( T o a p p r e c i a t e t h i s o n e ,
t h e e q u a t i o n . ) E a c h e n t r y C, j i s g i v e n b y t h e i n n e r p r o d u c t o f r o w i o f A a
c o l u m n j o f B. H e r e i s a s i m p l e e x am pl e .
(1 2 ) ( a + 2 c b + 2d )
3 4 x (: ;) = 3a + 4c 3b + 4d
5 6 5a + 6c 5b + 6d
v o i d M a t r i x : : ti m es ( c o n s t M a t r i x & b , M a t r i x & a n s ) c o n s t
{ a s s e r t ( n c = = b . n r } II c o m p a t i b l e d im e ns i o n s
f o r ( i n t i = O ; i < n r i i + + )
{ f o r ( i n t j = O i j < b . n c i j + + )
a n s . s e t E l e m en t ( i , j , r o w T im es C o l ( i , b . m a t , j , b . n c } };
Page 16
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 16/51
The function t i m e s insists on compatible dimensions by using the a s s e r t
macro, f rom < a s s e r t . h > , which calls a b o r t ( ) if the condition is not met. It
then multiplies the host matrix with b and deposits the product in the reference
parameter a n s .
Nested f o r loops are used to compute elements of the result. The private
function r o w T im e s C ol computes the inner product of row i of the host matrix
with column j of b . The result is stored as entry ( i , j )in a n s .
d o u b l e M at r i x : : ro w T i m e s C o l ( i n t i , d o u b le * b , i n t j , i n t b c ) c o n s t
{ d o u b le su m = O . O ;
f o r ( i n t k = O ; k < n c ; k + + ) s u m + = m a t [ i * n c + k ) * b [k * b c + j );r e t u r n su m ;
v o i d M a t r i x : : d i s p l a y ( ) c o n s t
{ f o r ( i n t i = 0 ; i < n r ; i + + )
{ s t d : : c o u t « s t d : : en d l « "( ";
f o r ( i n t j = 0 ; j < n c - l ; j + + )
s t d : :c o u t «m at [i * n c + j ) «"
s t d : : co u t «m a t [ i * nc + n c - l ) «"
A fully developed M a t r i x class would have many other functions. The
following program can be used to test matrix multiplication and display.
I I I I I I I t e s t M at r i x . C
# i n c l u d e " M a t r i x . h "
i n t m a i n ()
{ d o u b l e a [ 2 ) [ 3 ] = { { 1 . 0 , - 2 . 0 , 5 . 0 } , { 1 . 0 , 2 . 0 , 3 . 0 } } ;
d o u b 1 e b [3 ] [ 2 ] = { { 9 .0 ,7 .O } , { - 2 .0 ,3 .0 } , { - 1 . 0 ,4 .0 } } ;
M a t r i x x ( * a , 2 , 3 ) ; I I p a s s * a , n o t a
M a t r i x y ( * b , 3 , 2 ) ;
M a t r i x z ( 2 , 2 ) ;
x . t im es ( y ,z ) ;
z .di s p l a y ( ) ;
Page 17
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 17/51
And the output displayed is
8 21)
2 2 5 )
At this juncture, let's study some typical applications of arrays and pointers
to help sharpen the concepts presented. This example with exceptions added
can be found in Section 8.11.
Arrays and pointers are now applied in building a polynomial class. It is im-
portant that pointers are not studied in isolation but in conjunction with other
constructs to solve problems. By doing so, the abstract rules of pointer usage
become concrete and easy to grasp. The polynomial class again demonstrates
techniques for data abstraction and program encapsulation.
With the exception of numbers, polynomials are the most basic math-
ematical structures. They are widely used in many fields of study. Consider
establishing a class P o l y for one-variable polynomials with integer coefficients.
Such a polynomial has the familiar form
anxn + an_lxn-1 + ... + al x + ao
where x is the variable and an, an-I , ... , ao are the coefficients. The polynomial
has d egree n , and the leading coe f ficient an 1 = O.For example,
is a fifth-degree polynomial with four terms. Each term is a coefficient multi-
plied by a power of x. Such a polynomial can be represented by an i n t array
recording the power-coefficient pairs of each term. For instance,
i n t p o l l ] = { 5 , 3 , 2 , - 1 0 , 1 , 2 1 , O , - 8 , - 1 } i
gives the fifth-degree polynomial (4.1).The representation p o l begins with the
highest power, its coefficient,followed by the next highest power, its coefficient,
and so on. A minus one (-1) is used as an end marker because no negative
power is allowed for a polynomial. To conserve space, terms with a zero
coefficient are not included. Table4.1 shows how this representation works.
The polynomial representation and operations can be encapsulated in a
P o l y class declared with code similar to the following:
I I I I I I I P o l y . h I I I I I I I
# i n c l u d e < i o s t r e a m >
Page 18
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 18/51
T ab le 4.1 A P OL YN OMIAL REPRESENTATION
Representation
i n t p I [ ]
i n t p 2 [ ]
i n t p 3 [ ]
i n t p 4 [ ]
{ l o o , l , S o , l , o , l , - l } i
{ 2 o , 9 , 7 , - 2 9 , - l L
{o ,8 ,-1 }i
{ - l } i
x100 + X
50 + 1
9 x20 - 29 x7
8
a
pu b l i c :
P o l y ( ) { p o l = N U L L i }
P o l y ( c o n s t i n t * p , i n t t e r m s ) i
P o ly o p er a to r + ( c o n s t P o l y & q ) c o n s t i
P o l y o p e r a t o r - ( c o n s t P o l y & q ) c o n s t i
P o l y o p e r a t o r * ( c o n s t P ol y & q ) c o n s t i
u n s i g n e d i n t d e g ( ) c o n s t
{ r e t u r n ( p o l [ 0 ] > 0 ? p o l [ 0 ] : 0 ) ; }
v o i d d i s p l a y ( ) c o n s t i
1* o t h er m e m b e r s * 1
p r i v a t e :
i n t l e n g t h ( ) c o n s t i II l e n g t h o f p o l
i n t * p o l ;
II d e f a u l t c o n s t r u c t
II c o n s t r u c t o r
I I p o l y a d di t io n
I I p o l y s u b t r a c t i o n
II p o l y m ul t i p l i c a t i o
II d e g r e e
T h e c o n s t r u c t o r m a k e s s u r e t h a t t h e i n c o m i n g t e r m s a r e co p i e d i n t
s t o r a g e . T h e p o i n t e r p s u p p l i e s n t e r m s w i t h 2 * n i n t e g e r s b u t n o e n d m a
w h i c h i s s t r i c t l yf o r i n t e r n a l u s e . A z e r o p o l y n o m i a l i s i n s t a n t i a t e d i f n i s
I I I I I I I P o l y . C
# i n c l u d e " P ol y . h "
i n l i n e M A X ( in t x , i n t y )
i n li n e M I N ( i nt x , i n t y )
r et ur n x > y ? X Yi
r et ur n x < y ? X Y i
i n t n ) I I c o n s t r u c t o r
I I d y n a m i c a l l o c a t
i t t ) p o l [ i ] = *P++i
I I t e r m i n a t o r
P o l y : : Po l y (c o n s t i n t * p ,
{ n = 2 * n ;
p o l = n e w i n t [ n + 1] i
f o r ( i n t i = o i i < n
p o l [ n ] = - 1 ;
Page 19
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 19/51
The private member length counts how many ints are in the represen
tion pol:
int Poly: :length() const
{ int i;
for (i=O ; pol [i) > -1
return i+1;
The member function operator+ is a little more complicated and can
defined as follows:
int *c, *a, *b, *tmp;
unsigned len, d;
len = length()+q.length()-l;
d = 1+2*(1+ MAX(deg(), q.deg()));
len = MIN(len, d); II tmp = c = new(int[len)); II
a = pol; b = q.pol;
while (*a >= 0)
{ while(*b > *a)
{ *c++ = *b++; *c++
*c++ = *a;
if (*a == *b)
{ *c = *++a + *++b;
if (*c++ 0) c
b++;
max length of answertemporary space for result
II for each term of a
II terms in b of higher powe
*b++; }
}
else *c++
a++;
}
while (*b >= 0) *c++ = *b++;
* c = - 1;
Polyans(tmp, (c-tmp)/2);
delete tmp;
return ans;
II add leftover terms in b
II terminator
I I answer object
II free temporary space
In Poly: :operator+, the maximum size of the result polynomial is compute
and then that much space is allocated with new to hold the temporary res
The sum computation now continues depositing terms in tmp using c a
running pointer.
To compute the sum, each term of a is added to the unprocessed terms
b with a power greater than or equal to the current term. The resulting ter
are stored in c. When two terms from a and b combine (line I), a check is m
Page 20
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 20/51
to see whether the new term is zero due to cancellation. If so, the c p
is decremented by 2 to lose the zero coefficient and its exponent (line 2
iteration continues until all terms of a and b have been processed. Final
-1terminator is inserted at the end of c.
Now all we have to do is establish a Poly object with the correct nu
of terms (line 3), free up the temporary space (which may be too large f
actual result), and return ans.
Note that ans is an automatic variable, so it is destroyed after operato
returns. This is not a problem because a copy of the value of ans is ret
and not ans itself. The situation is entirely the same as returning an in
float local variable.
For testing purposes, various polynomials should be added and the r
displayed. Having a member function display is handy:
void
{
Poly: :display()
int *p = pol;
switch ( *p )
{ case -1: cout
case 0: cout
default:
« "0" « endl; break;
« p[l] « endl; break;
II zero poly
II constant poly
cout « I (' i
while ( *p >= 0 )
{ cout « *p « " " « *(p+1);
p += 2 ;
if (*p != -1) cout « " " .I
A constant polynomial is displayed as an integer (lines A and B). No
using declarations allow the direct use of cout and endl without the name
(Section 3.2) scope operator std: :.
It is clear that many other members must be defined before the Poly
is complete. But you can already write a main program to test the Poly
and to display some polynomials.
Standard C++ supplies vector objects that can be used just like arrays bu
certain advantages. The dimension of a vector grows dynamically. Ra
Page 21
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 21/51
access to elements through indexing as well as inserting new elements at
end are very eff icient.
Youinclude the header file <vector> to use vectors. The code
#include <vector>
using std: :vector;
establishes arr as a vector object for size elements of the given t ype.
example,
vector<int> iv(16);
vector<Fraction> f v(32);
II vector of 16 ints
II vector of 32 f ractions
establishes i v (f v) as a vector object for 16 ints (32 f ractions). To decla
vector of objects, make sure the class has a default constructor.
A vector object can be indexed just like an array:
iv[O]
iv[1J
1 0 ;
iv[O] - 4;
If the ind e x is inv alid , the value r et urned m ay b e wrong. Tokeep indexing effic
vector does not detect out-of-bounds indices.
Initial value can be supplied when instantiating a vector:
vector<double> dv(256, 0.0);
vector<int> iv2(ia, ia+15);vector<string*> sv;
II vector of 256 entries, init to 0
II init by ia[O] to ia[14]II empty vector of string*
A vector records its size. Thus, you can write code such as
for ( int i=O; i < dv.size(); i++ )
The vector has another important advantage over primitive arrays:
can insert elements at the end of a vector, and the size of the vector will g
as needed:
iv . insert (i v .end ( ), i); Inserts i at back of i v (same as i v .push..back (
It is possible to insert elements at the beginning or in the middle:
i v . insert (iv .begin ( ), j); Inserts j at front of i v (linear time)
i v . insert (i v .begin ( ) +i, j); Inserts j just before i v [i] (linear time)
but these two operations are inef ficient, incurring a cost proportional to
length of the vector. Choose another data structure if your application call
frequent insertion / deletion at the beginning or in the middle of the eleme
Page 22
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 22/51
The begin () member function of vector returns a pointerl to the
element while end () gets you one that points just beyond the last elemen
Similarly, you can delete elements from the vector with
i v .pop.-back () ; Removes last element of i v
i v .erase (i v .begin () + i); Removes element i v [i ] (linear time)
The capacity of a vector is the maximum number of elements it can
before having to grow into a larger vector. After instantiation, the vecto
pacity is the same as its size. The capacity grows, by ever-larger increm
as more elements are inserted. Growing a vector can involve copying all
ing elements. You can reserve enough capacity for a vector initially to a
unnecessary growing.
av.reserve(512);
av .push.-back (susan) ;
Capacity set to 512
Inserting account
A vector stores the value, a copy, of whatever is put on the vector. Thus, a
of the account susan, not the object itself, is placed in avo
These operations and the fact that it grows in size automatically ma
vector object easier to use than a primitive array in many situations.
information on vector as part of the Standard Template Library can be f
in Section 11.2. Let's put vector to use in a practical application.
Ordering or sorting lines of text is commonplace in data-processing app
tions. Let's now consider a simple sort program. The command mysort is
in the form
It reads all lines with cin, sorts the lines by comparing the given key i
lines, and then writes out the sorted lines with coutoEach line is assum
contain one or more fields separated by white spaces (SPACE or TAB). Th
is an integer indicating which field to use for ordering the lines. If the k
unspecified, whole lines are compared.
Page 23
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 23/51
Laura Wang A
Paula Kline C
Richard Brown B
The command mysort can be used on such files:Use key position 2 to sor
last name and key position 3 to sort by letter grade.
Taking an object-oriented view, we can identif y two useful objects:
1. A TextLines object, which holds the input text lines, provides acce
individual lines, knows how to interchange any two lines, and can
output the ordered lines to any given output stream.
2. A SortKey object, which compares the designated keys within any
text lines.
With these objects, the implementation of the mysort command consis
the following major steps:
1. Establish a TextLines object, txtobj, to hold the input lines.
2. Establish a SortKey object based on the key position and delimiter
characters.
3. Apply quicksort using these objects and then ask txtobj to display
itself to couto
All of this is tied together with a main program which first processes
command-line arguments and then performs the three steps just listed.
This example is more extensive than any we have seen so far. It p
pointers, strings, vector, and many other constructs to use in one example
description is organized according to the preceding outline. The example
shows how to break down a complicated program into independent obj
that interact to perform the task at hand.
After a TextLines object is initialized, lines can be read and stored wi
the object. A vector of string*, with a default capacity of 512, is use
hold the text lines (lines 1 and 2). Because a vector can grow dynamic
there is no prior upper limit to the number of lines. Storing string poin
makes interchanging lines easy and efficient. The operations provided incl
reading text lines (input), interchanging lines (swap), inserting and remov
Page 24
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 24/51
a l i n e , a c c e s s i n g i n d i v i d u a l t e x t l i n e s b y i n d e x i n g ( [) ), r e p o r t i n g t h e n u m b
o f l i n e s ( l e n g t h ) , a n d d i s p l a y i n g t h e l i n e s ( d i s p l a y ) :
I I I I I I I T e x t L i n e s . h I I I I I I I
# i n c l u d e < i o s t r e a m >
# i n c l u d e < v e c t o r ># i n c l u d e < s t r i n g >
u si ng s td :: s t r i n g ; u si ng s td : : i s t r e a m ; u s in g s t d: :v e ct o r;
c la ss T ex tL i n e s
p u b l i c :
T e x t L i n e s ( i n t c a p = 5 1 2 ) { l i n e . r e s e r v e ( c a p ) ;
i nt l e ng t h( ) { r e t u r n l i ne . s i z e ( ) ;
v o i d s w a p ( i n t i , i n t j ) ;
v o i d i n p u t ( i s t r e a m & i n ) ;
v o i d r em o v e ( i n t i ) ;- T e x t L i n e s ( ) ;
s t r i n g * o p er a to r [) ( i nt i ) c on s t
{ r et ur n ( i > = O & & i < l i n e . s i z e ( ) ) ?
}
v o i d d i s p l a y ( o s t r e a m& o u t) c o ns t ;
b o o l i ns er t( c o n s t s t r in g& 1 , i n t i ) ;
p r i v a t e :
i nt r ea dL i ne s( is tr ea m & i n) ;
v e c t o r < s t r i n g * > l i n e ;
II s w a ps l in es
II r e ad s l i n es i nt o
II r e m o v e s l i n e iII d e s t r u c t o r
II g e t s l i n e i ( 2 )
l i n e [ i ) : N U L L ;
I I p er fo rm s l i n e r ea d
II v e c t o r o f s t ri n g*
O v e r l o a d i n g t h e [ ) o p e r a t o r ( l i n e 2) m a ke s i t po s s i b l e t o u s e i n d e x i n g
a T e x t L i n e s o b j e c t . T h u s , i f t x t o b j i s a T e x t L in es o bj ec t , t h e n
i s a c o n v e n i e n t w a y t o o b t a i n l i n e n . T h e o p e r at or [ ] d e f i n e d h e r e c h e c k s
i n d e x a n d r e t u r n s N U L L f o r i n d e x o u t o f r a n g e .
A l s o s w ap a n d r e m ov e a r e i n l i n e f u n c t i o n s d e f i n e d i n t h e h e a d e r f i l
o u t s i d e o f t h e c l a s s d e c l a r a t i o n .
i n l i n e v o i d T e x t L i n e s : : s w a p ( i n t i , i n t j )
{ s t r i n g * t m p = l i n e [ i ] ;
l i n e [i ) l i n e [ j ) ;
l i n e [ j ) = tm p;
i n l i n e v o i d T e xt L in e s: :r e m o v e ( i n t i )
d el et e l in e [ i ) ;
l i n e . e r a s e ( l i n e . b e g i n ( ) t i ) ;
Page 25
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 25/51
Clearly,a TextLines objectis useful whenever aprogram deals with lin
text from standard input or a file. This is another concrete example of buil
components that are reusable in many places - a significant advantag
OOP.A user of TextLines need not know how it is implemented. Access to
header file is enough. Implementation details are hidden in the TextLin
file:
I I I I I I I TextLines.C I I I I I I I
#include <iostream>
#include "TextLines.h"
using std: :getline; using std: :ios;
using std::cin; using std: :cout;
using std: :cerr; using std: :endl;
void TextLines: :input (istream& in)
{ int 1 = readLines(in);
if (1 > 0 ) return;i f ( 1 == - 1 )
cerr «"TextLines: Failed to read input file" «endl;
i f ( 1 = = 0 )
cerr «"TextLines: Input file empty" «endl;
in.setstate(ios: :badbit); II input f ailed
Themember input callsthe active routine readLines to read lines. The func
readLines returns the number of lines read if successful. If the value retur
is -lor 0, appropriate error messages are displayed, and the badbi t oinput stream is set (line A). Setting badbi t causes in. bad() to return true.
The readLines function reads each line into a string using the get
function (line B) from the Standard Library (Section 2.5). The string is
inserted at the end of the vector to hold the lines (line D). Input failu
check ed (line C), and an error code or the number of lines read is retur
(line E).
int TextLines: :readLines(istream& in)
int error = 0, count = 0;
string* tl = new string();while ( getline(in, *tl, ' \ n')
{ if ( in.f ail() )
{ error = -1; break;
line. push_back(tl) ;
count++;
tl = new string();
II
II input f ailed
Page 26
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 26/51
Page 27
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 27/51
p u b l i c :
e x p l i c i t S o r t K e y ( i n t p o s
{ d e l i m = d l m ;
p o s i t i o n = p o s ;
}
v o i d s e t D e l i m (c o n s t c h a r * s ) { d e l i m = s ; }
II c o m p a r e l i n e si n t l i n e C o m p a r e ( c o n s t s t r i n g & a , c o n s t s t r i n g & b ) c o n s t ;
i n t k e y C o m p a r e ( c o n s t s t r i n g & k , c o n s t s t r i n g & 1 ) c o n s t
{ r e t u r n k . c o m p a r e ( k e y ( l ) ) ; }
p r i v a t e :
s t r i n g d e l i m ;
i n t p o s i t i o n ;
II e x t r a c t k e y
c o n s t s t r i n g k e y ( c o n s t s t r i n g & s ) c o n s t ;
I I t o k e n d e l i m it e r s
II k e y t o k e n p o s i t i o n
C a r e h a s b e e n t a k e n i n u s i n g r e f e r e n c e p a r a m ete r s a n d i n d e c l a r i n g t h e m c o n
a p p r o p r i a t e l y . Y ou s h o ul d d o t h e sa m e i n y o ur C + + p ro gr am s .
T h e f u n c t i o n k e y e x t r a c t s t h e s o r t k e y s w i th m e m b er f un c t i o n s o f s t r i n
str 1. find_first_of (st r 2 , i ) ;
st r1. find_first-.not_of (st r2 , i ) ;
E x a m i n i n g str1 f r o m p o s i t i o n i ,t h e i n d e x o f t h e f i r s tch a r a c t e r t h a t i s ( i sn
c o n t a i n e d i n s t r 2 is re t u r n e d . I f n o s u c h c h a r a c t er i s f o u n d i n s t r 1 , t h e c o n s t a
s t r i n g : : n p o s i s r e t u r n e d . T he a rg u m e n t st r 2 c a n b e g i v e n e i t he r a s a s t r i
o b j e c t o r a C - s t y l e s t r i n g.T h e f u n c t i o n s a r e p u t t o g o o d u s e s k i p p i n g f i e l d p o s i t i o n s ( l i n e F ) t o e x t r
t h e d e s i r e d k e y ( l i n e G ) . A n e m p ty s t r i n g o b j e c t i s r e t u r n e d i f t h e l i n e s d o
n o t c o n t a i n t he ke y f i e l d i n d i c a t e d b y p o s i t i o n.
11 /1111# i n c l u d e
# i n c l u de
# i n c l u d e
S o r t K e y . C
< i o s t r e a m >
< s t r i n g >
" S o r tK ey . h "
c o n s t s t r i n g S o r t K ey : : k e y
( c o n s t s t r i n g & s ) c o n s t
i n t i = p o s i t i o n ;
i f ( i = = 0 ) r e t u r n s ;
i n t i O = O , i l = O ;
w h i l e ( i - - > 0 )
{ i f ( i l = = s t r i n g : : np o s
r e t u r n s t r i n g ( ) ;
i O s . f i n d _ f i r s t _ n o t _ o f ( d e l i m , i l ) ;
i f ( i O = = s t r i n g : : n p o s )
II k e y t o k e n p o s i t i o n
II w h o l e l i n e a s k e y
II s t a r t a n d e n d i n d i c
I I s k i p p i n g ( F )
Page 28
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 28/51
return string() i
il s.f ind_f irst_of(delim, iO) i
}
if ( il == string: :npos )
i1 = s.length();
return string(s, iO, il-iO);
II length of s
I I key f ound
The 1ineCompare member function compares two text lines. Ba
lineCompare compares the two whole lines or, if a key position is given
pares the two key fields:
int SortKey: :lineCompare
(const string& a, const string& b) const
{ if (position == 0) return a. compare (b) i
return key(a) .compare(key(b));
The member function compare of string is handy here.
The function lineCompare returns positive, zero, or negative for
greater than, equal to, or less than line b, respectively. This is consistent
the C/C++ convention and is what theparti tionroutine of quicksort ex
The objective of this part of the program is to take the text lines in txtob j
sort them into order by comparing the appropriate keys.
The approach is to adapt the quicksort procedure used for integer
(Section 3.4) to the TextLines object txtob j. The recursive function quic
itself is mostly the same as before. However, now txtob j . swap interch
lines. Furthermore, the partition function uses lineCompare of the
SortKey to compare two lines using the user-specified keys:
I I I I I I I mysort.C I I I I I I I
#include "TextLines.h"
#include "SortKey.h"
int partition(TextLines& txtobj, int 1, int r,
const SortKey& sk )
register int i=l, j=ri
string piVi
II middle element as pivot
txtobj.swap((i+j)/2,j);
piv = *txtob j [j]; II line j of txtob
while (i < j)
{ while (sk lineCompare(*txtobj[i] piv) II compare sort k
Page 29
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 29/51
w h i l e( j > i & & s k. l i n eC o m pa r e ( * t xt o b j [ j ] , p i v ) >= 0)
j--;
i f ( i < j ) t xt o b j .s w a p ( i + + , j );
}
i f ( i != r ) t x t o b j .s wa p ( i , r ) ;
r e t u r n i ;
v o i d q u i ck so r t ( T e x t Li n e s& t x to bj , i nt 1 , i nt r , c on st S or tK ey & s k
{ i n t k;
i f ( 1 >= r I I 1 < 0 I I r < 0) r e t u r n ;
k = p ar t it i on ( t xt ob j , 1 , r , s k) ;
q u i c ks o r t ( t x t ob j , 1 , k- 1 , s k) ;
q u i c k s o r t ( t xt o bj , k + 1, r , s k);
Making t x t o bj a reference formal parameter is critical to these sortroutines. The basic logic of qu i c k s o r t and p a r t i t i o n stays the same. T
S o r tK e y s k is instantiated by the main program:
# i n c l ud e < i o st r e a m >
u s i n g s t d : : e n dl ; u s in g s t d: : c ou t ; u s i ng s t d : : c e rr ;
i n t ma in ( in t a rg c , c ha r* a r g v[ ] )
{ i f ( a r g c > 2 )
{ c e r r « " U s a g e : " « a r g v [ O ] « " ke y - p o si ti on " « e nd l;
r e tu rn 1 ;
}
S o rt K ey S ki
i f ( ar gc = = 2 ) s k = S o r t K e y ( a t o i ( a r g v[ l ] ));
T e x t Li n e s t x t o b j ;
t x t o bj. i n p u t ( c i n ) ;
i f ( c in . b a d( ) )
{ c e r r « " f ai l ed r e a di n g i np ut . " « e n d l;
r e t u r n 1 ;
}
qu i c k s o r t (t xt o b j , O, t xt o b j. l en gt h( )- l , s ki ;
t xt o b j .d i s p l a y ( c o ut ) ;r e t u r n 0 ;
The library function atoi converts a numeric string to an integer. The test
line H checks the condition set on line A in function T e x t L i n e s: :i n p u t .
All of the parts are now in place. The main program processes comma
line arguments and sets up the S o r t K e y object. The program then get
T e x t L i n e s object t x t o b j, reads input lines into it, applies qu i c k s o r t pa
ing to it sk to make comparisons, and then asks t x t o b j to display itself. T
Page 30
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 30/51
simple and clear structure of the main program testifies to the advantag
the OOP approach.
Compile the binary files TextLines .a and SartKey. a first and then si
combine mysart .a with them to get mysort. For example,
g++mysart.a SartKey.a TextLines.a -a mysort
gets you the executable file mysort. Run it with
mysort 2 < somef ile
to see somefile sorted by key field 2.
The examples in this section and Section 4.5 (found in ex04 / of the
package) not only show array, pointer, vector, and string usage bu
demonstrate how to identify interacting objects that can be programme
dependently. Object orientation not only makes programs easier to writ
more important, also makes the components useful in many other situat
Let's now turn our attention to the usage ofpointers and arrays in function
All aspects of pointer usage related specifically to function calls are col
in this section for easy ref erence.
When a pointer is passed by value in a function call, a memory addr
passed. In most cases, the address is the location of a variable, an array
or an object. If x is a variable, ptr a pointer variable, arr an array, arr2 a
dimensional array, and obj a class object, then the expressions in Table 4
all valid forms of pointers.
To specify a simple pointer formal parameter y in a function heade
two forms
type *y and t y pe y []
are equivalent, and both are commonly used. The second notation impliey is a pointer to the beginning of an array. Extending the equivalence, the f
typ e **y and type *y[]
are again the same in function headers. Therefore, the command-line argu
char * argv []
can, in a function header, also be written as
Page 31
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 31/51
&x
&ab j
ptr
ptr++
arr or &arr [0]
arr + 2 or &arr [2]
&arr2 [0] [0] or arr2 [0]
Address of x
Address of class object
Value of pointer variable ptr
Value of pointer variable ptr
Value of constant array name arr
Address of third entry of array arr
Address of first entry of two-dimensional
arrayarr2
Address of first entry of row i + 1 in
two-dimensional array arr2
When a pointer is passed to a function, the called function knows the
and the starting location of a piece of data but not necessarily where it e
For example, the formal parameter int *y can be used to receive the addres
a single integer or an array of integers. Clearly, some other arrangement m
be made. Using a special terminator is a convenient way to define the ex
of a data item. The conventional terminator 1 \ 0 1 for C-style character str
is a good example. Independent of whether there is a terminator, it is alw
possible to use another integer parameter to pass the size information in
called function, as in istrearn: :read of the I / O stream library (Section 6.7
There are two possible purposes for passing a pointer into a function:1. Togive the called function access to data without making a copy.
2. To have the called function initialize or modif y the data.
The data in question may be global, local to the calling function, or alloc
in the scope of some function in the chain of function calls. More details
these two modes of usage are discussed next.
A data item passed by pointer or reference is read -onl y if it is not modifiedthe called f unction. The parameter of strlen is a typical example of a re
only pointer. Counting the number of characters does not modif y a str
The canst modifier (Section 3.9) should be used for such a formal parame
allowing the compiler to detect any unintended attempt to modify the d
The treatment of such a violation is implementation dependent, but a warn
is usually generated. Furthermore, in making a function call, it is critica
Page 32
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 32/51
know whether an object passed by pointer will be modified or not.
consistently, the presence or absence of const in a function prototyp
convey this important information.
One reason for a function to modif y an objectpassed by pointer or ref
is to transmit results computed back to the calling function. Many l
functions depend on this feature; get line is an obvious one. A parameter
to transmit computed results back to the calling function is known as a
paramet er . The matrix multiplication routine Matrix: :times (Section 4.4
just such a return parameter for the product matrix. When a function is
with a return parameter, it is the calling function's responsibility to a
enough space of the correct type to accommodate the returned value.
Just like the operator new,a function can also produce a pointer as a
value. However, be careful when you define a function that returns a p
The returned pointer must not point to a local variable in the scope
returning function. An automatic variable in a function is destroyed
the function returns. Certainly, it does not make sense to return a poin
something that disappears. For example, it is incorrect to use
int *bad(int x)
int Yi
y=
x * X i return &y;
This function produces no syntax error when compiled and will actuall
cute. Unfortunately, when the returned pointer isused, it may be pointin
memory cell that has been destroyed (used for other purposes). A pointe
has lost its object in memory is referred to as a danglin g pointer and sho
avoided.
When a function returns a pointer, mak e sure that it points to one
following:
• Memory cells supplied by the calling function.
• External data.
• Static data in the function.
• Dynamically allocated space.
The function Poly:: operator+ () (Section 4.5) is an example wh
pointer to memory allocated by newis returned. When such a pointer
Page 33
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 33/51
A class destructor (Section 5.7) can of ten help in this regard. In other ca
clear documentation of the dynamic nature of the returned pointer mus
provided to callers of the function.
A C++ reference is not a basic data type but an alias for a variable or a c
object. In many situations where a pointer formal parameter is needed
reference parameter can be used instead. Certainly, passing an argument
reference involves no copying, and changes made to a reference modif y
original. When passing a reference argument, mak e sure it is an lvalue
reference parameter is sometimes simpler to use than a pointer because th
is no need for any indirection notations such as *ptr or ptr->member.
When passing arrays, it is advisable to pass pointers rather than referen
An array name, not being an lvalue, actually cannot be passed to a refere
parameter or used to initialize a ref erence variable. A pointer variable sho
be used instead. Thus,
void f (int* &ptr_ref );
int arr [] {l, 2,3,4} ;
f ( arr );
int* ap = arr;
f ( ap );
II error; arr is a constant pointer
II pointer variable ap
II o . k .
A f unction can also return a ref erence (Section 3.8). A local variable in
returning function is a bad choice as a reference return value. The variab
destroyed after the function returns. In addition, there can be neither poin
to references nor arrays of references.
A variable x may be used to access a memory celld irect l y (Figure 4.7). The v
of x is stored in its associated data cell.As stated before, however, the cell
pointer variable ptr stores the address of another data cell whose content be accessed indirectly through the value of ptr using the value-of operato
The quantity *ptr can be treated just like a variable and can be used on
left-hand side of an assignment.
A pointer provides one level of indirection. It is possible to have do
ind ir ec t ion if the value of *ptr is also a pointer. Ref erring again to Figure
the value of ptra is the pointer variable *ptra, and the value of *ptra is an
variable **ptra, which has the value 15.
Page 34
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 34/51
1 5
x
0 . . 1 5
ptr *ptr
. . 0 . . 1 5
*ptra **ptra
double ind ire ct 0 --- --- <.-
ptra
declares the variable ptr to be of type int *, not *prt of type int as
programmers may mistakenly suppose. Similarly, the declarations
char * * C i
char * * * d i
give c type char ** and d type char ***,respectively. A handy example
type char **is the array char *argv [] for command-line arguments. T
is possible. In fact, we have already used a few variables of type ch
including the lines in the sorting example (Section4.7).
To understand the meaning of d, think of it as the address of an ar
different groups of text lines:
d[O] is line_groupl
d[l] is line_group2d[2] is line_group3
Multiple indirection tends to be confusing and error-prone. The situ
can be helped by the appropriate application of typedef . Consider
typedef char *C_stringi
typedef C_string *Linesi
typedef Lines *Groups of lines;
Page 35
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 35/51
making it much easier to deal with: The type of *dis Lines, the type of
C_string, and the type of ***dis char. (Section4.13 contains an example
uses multiple indirection.)By the way, typedef not only helps to decipher multiple indirection
also to simplif y other complicated constructs, as we will see shortly. A
may have its own typedefs as part of the class declaration.
Normally, functions are written to work on arguments of specific types. T
even if there is already a quicksort for an array of integers, there is still no
to sort character strings, doubles, or fractions. However, with a combin
of techniques, it is possible in C++ to write a type-independent, or gen
function that works for a multitude of different types of arguments.
Our discussions here ultimately lead to an implementation of quick
that sorts arbitrary data in any caller-specified ordering. To achieve this
three distinct but related topics must be presented:
1. Pointers to functions.
2. Formal functional parameters.
3. The type void *.These same mechanisms also help define generic classes (Section
where arbitrary types can be treated by objects of the class. Genericness m
programs widely applicable and reusable. C++ also offers a templat e m
nism (Chapter 10)that can be very useful when writing generic programs
example, vectors of different types can be created with the simple tem
notation vector< type > .
Ordinarily, we think of the values of a variable or formal parameter as
kind of data or objects. A whole new dimension opens up when the v
can be functions. Functions can be passed as arguments in a call, and
called function can apply the passed function in conjunction with its
preprogrammed procedures. An argument that is a function is known
funct ional argument. Furthermore, an object can contain variables that are
names of functions at (or after) initialization time.
Page 36
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 36/51
The flexibilityprovided by functional variables / arguments is tremen
Imagine, now you can write a function that follows different procedur
different invocations. In other words, with functional arguments, a fu
not only works with different input data but also utilizes different inc
functions. Just consider how much more a sort program can do if it is sup
with the appropriate comparison f unction each time it is called.Because the functional variable / argument is an extraordinary featu
all languages support it. Fortunately, this feature i s available in C++
functional variables / arguments take the form of point ers tofunc tions. Let
a close look at how to use functional arguments, how they work, and wh
be achieved with them.
Pointers to Functions Once a function is defined, the function
preceded by the &operator is a pointer to the function-namely, the adwhere the function's definition begins in memory. A function pointer, ju
any other pointer, can be assigned to pointer variables of the right typ
also passed as an argument in a function call.
For example, given a function average defined as
int average (int x, int y )
return ( x + y )/ 2 i }
int ( * fn) (int, int);
fn = &average;
int var = (* f n) (14,26) i
var = f n(14,26)i
II declare function pointer variable
II function variable assignment
II f unction call through pointer
II shorthand call through pointer
First, the functional variable fn is declared to be a pointer to any functio
takes two int arguments and returns an int value. (The general synt
functional variable declaration will be given presently.) Second, f n is ass
the address of the function average. Then, (* fn), or simply fn, can be
as a function name in making a call to average.
Toproduce a function pointer, the &in front of the function name ca
be omitted. Thus,
is fine, too. This notation is simpler and is used f rom now on. In case av
is an overloaded function, a pointer to the correct version will be produc
deducing it from the signature used in declaring fn
Page 37
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 37/51
Declaring a functional variable may look complicated, but it is really
ple. Just use the function prototype with the function name replaced by
notation (* var ) . Specifically,the general form
declares the variable var to be a pointer to a function that takes the spec
arguments and returns values of the given type.
A functional variable declaration looks strange because it deviates from
normal syntax of variable declarations. What confuses people is the posi
of the declared variable relative to the other parts in such a declaratio
may take a little getting used to, but the position is perfectly well defined:
variable is put w here the funct ion nam e w ould be in a function prototype.
examples in Figure 4.8 should help as well. More generally, complicated
declarations can be deciphered by realizing that a de claration always spells
how the declared variable is used. For example, the first declaration in Figurshows that (*fn3) (3.5, 6.7) is a function call that returns a float.
Since a functional variable declaration is somewhat long and complic
to look at, we can simplify things greatly by using typedef. For instance,
defines the type name INT]N.Note that the type name is placed where
variable would be. INT]Ncan then be used to declare any functional vari
of that type. In particular, we can declare fn in the average example with
Figure 4.8 DECLARING FUNCTION POINTERS
V alue_type V ar Arg u ments
l l l f loat (* fn_a) (float, float) ;
float (* fn_b) (int) ;
void (* fn_c) (char *, int);
char * (* in_d) ( );
Page 38
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 38/51
Formal Functional Parameters The purpose of a f unction var
almost exclusively, is to pass a function name to another function or
object. Tomake things easy to understand, let's examine an artificial exa
int mystery(int a, int b, int (* fn) (int, int))
{ return f n(a,b);
}
Here the function mystery takes three arguments: two integers and a f unc
parameter fn. The declaration of the formal parameter f n is, as it shou
the same as declaring a variable of the intended type. By using the ty
INT_FN, we can code a simpler looking version of mystery:
int mystery(int a, int b, INT_FN fn)
{ return fn(a,b);
}
The function mystery simply calls the f unction pointed to by fn and re
the value of the call. Here are some functions, in addition to average, th
be passed to mystery:
extern int gcd(int a, int b); (The gcdfunction is defined in Sectio
int sqsum(int x, int y)
return (x * x + y * y);
Here is how to make calls to mystery. Note that the names averageand sqsumare pointers to the definitions of the functions:
int main()
{ cout« mystery(16, 30, average) « endl;
cout « mystery(3, 4, sqsum) « endl;
cout « mystery(312, 253, gcd) « endl;
return 0;
II is 2 3
II is 2 5
II i s 1
In fact, any function that takes two int arguments and returns an int c
passed to mystery.The one topic that remains on our discussion list is the void * poin
mechanism to pass data or objects of arbitrary type and a necessary co
ment to the functional argument facility.
To write a function that applies the same algorithm in a variety of situa
we need the functional argument mechanism described earlier But in
Page 39
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 39/51
cases, we also need the ability to receive d ata o f arbit r ary , or unspecified , ty
The ability of a function or class to work on different data types is know
generic ness, and programs exhibiting such a capacity are generic.
Let's begin with a simple example of determining the length of an arbit
array. The strategy is to write a function that takes the following two argume
1. An arbitrary array.
2. A test function for the end of the array.
The function arblen computes the length of the array anywithout know
anything about its type. Thus, arblen is a generic array-length function.
functional parameter isEnd is the supplied function that detects the termina
of the given array. What arblen does is simply call isEnd repeatedly and co
the number of calls. The count is then returned when isEnd detects the en
the array:
int arblen(void *any, END_FNisEnd)
int len=O;
while ( ! isEnd(any, len) ) len++;
return len;
A variable or formal parameter of type void * (pointer to unknown tcan receive a pointer of any type. This provides a way of passing dat
arbitrary type into a function. Because the data type is unknown, there are v
few allowable operations on a void * variable other than referencing (u
the pointer value) and passing it to another function. In particular, index
value-of (*), increment, decrement, and other address arithmetic operati
are illegal or unsafe on a void *variable. Even so, the void * type is critic
processing arbitrary data, as seen in the function arblen.
Totest arblen, we define two terminator detecting functions, int_end
str_end, for nonnegative integer and character arrays, respectively:
bool int_end(int *a, int i)
{ return a[i] == -1;}
bool str_end(char *a, int i)
{ return a[i] == ' \ 0 ' ;
}
Page 40
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 40/51
Now, f or testing, we use the following main function:
int main()
char a[]="abcdefg";
int b [ ] = { O , l , 2 , 3 , 4 , -1 }i
int i = arblen(a, reinterpret_cast< END_FN>(str_end) )i
II lengcout «"length of string = " «i «endl i
i = arblen(b, reinterpret_cast< END_FN>(int_end) )i II leng
cout « "length of int array = " « i « endi;
return O i
Note that explicit type-casting, reinterpret_cast< END]N > (str_end)
used on the function pointers to make the argument match the declared fo
parameter isEnd of arblen. This also allows passing the void * argumen
stLend.Since void * is so useful, a good question is, Can we also mak e u
void & , an arbitrary reference? Unfortunately, C++ does not permit void
The preliminaries are now finished. Weare ready for some practical a
cations culminating in the implementation of a generic quicksort.
Let's consider how void *and functional arguments combine to define gen
functions. Our first example is a function that checks to see whether all enof an array satisf y some given condition. Questions such as
• Is every entry an even / odd number?
• Is every entry positive?
• Is every entry zero?
• Is every character lowercase?
are often asked. We can write one generic function, and_test, that takes
of them all. The and in the name expresses the concept of logical-and: All
must be true before the answer is true:
bool and_test(void *any, BOOLEAN_FNtest, END_FNisEnd)
{ int len=Oi
while ( ! isEnd(any, len) )
{ if ( test (any, len) == 0 ) return falsei
len++i
Page 41
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 41/51
The type name BOOLEAN_FNalso documents the f act that f unctions of this
must be Boolean , or one that returns a true or false value. The arbitrary Boo
test is applied to each array entry successively until the end is found by
supplied terminator detector isEnd. The first failed test causes and_tesreturn f alse. The value true is returned after the array is exhausted. Candi
functions to pass to the parameter test are
bool even(int *ip, int j) { return (ip[j] & Ol)==O;}
bool odd(int *ip, int j) { return (ip[ j] & Ol)==l;}
bool clower(char *cp, int j) { return islower(cp[j]);
The function or_tes t is similar but is designed to answer questions suc
• Is there an even / odd entry?
• Is there a negative entry?
• Is there a zero entry?
• Is there an uppercase character?
Again, the or indicates the logical-or concept: If at least one test is true
answer is true:
bool or_test(void *any, BOOLEAN_FNtest, END_FNisEnd)
{ int len=O;
while ( ! isEnd(any,len)
{ if ( test (any, len) return true;len++;
}
return false;
Our next example further illustrates the flexibility that functional argum
provide. Let's write a sorting program that can rearrange a sequence of it
o f an y t y pe into any speci f ied ord er , thus making the sorting program gen
and very reusable. The strategy is to modif y the quick sort program to use
following three arguments:
1. An arbitrary array.
2. A caller-specif ied comparison f unction crop.
3. A supplied element-interchange function swap.
Page 42
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 42/51
t y p e d e f i n t ( * C M P _ F N ) ( vo i d * , i n t , i n t ) ;
t y p e d e f v o i d ( * S WA P _ F N ) ( v o i d * , i n t , ' i n t ) ;e x t e r n v o i d q u i c k s o r t
( v oi d * a ny , II a rb i t r a r y a r r a y t o b e s o r t e d
i n t 1 , I I s t a r t i n d e x
i nt r , I I e n d i n d e x
C M P _ F N c m p , II s u p p l i e d c o m p a r i s o n f u n c t io n
S W A P _ F N s w a p II s u p p l i e d i n t e r c h a n g e f u n c t i o n
) ;
1111111# i n c l u d e
a r b q s o r t . C
" a rb q so r t . h "
v o i d q u i c k s o r t ( v o i d * a n y , i n t 1 , i n t r , C M P _ F N c m p , S W A P _ F N s w a p )
{ i f ( 1 > = r I I 1 < 0 ) r e t u r n ;
II c a l l w i t h s u p p l i e d f u n c t i o n s
i n t k = p a r t i t io n ( a n y , 1 , r , c m p , s w a p ) ;
I I r e c u r s i v e c a l l s
q u i c k s o r t ( a ny , 1 , k - l , c m p , s w a p ) ;
q u i c k s o r t ( a n y , k + l , r , c m p, s w a p ) ;
T h e p a r t i t i o n f u n c t i o n, w h i c h i s p l a c e d b e f o r e q u i c k s o r t i n t h e a c t
f i l e ,n o w b e c o m e s
s ta t i c
i n t p a r t i t i o n ( v o i d * a n y , i n t 1 , i n t r , C M P _ F N c m p, S W A P _ F N s w a p )
{ r e g i s t e r i n t i = l , j = r ;
II c h o o s e m i d d l e e l e m e n t a s p e
s w a p ( an y , ( i + j ) 12, r ) ;w h i l e ( i < j )
{ w h i l e ( cm p (a n y , i , r ) < = 0 & &
w h i l e ( j > i && c m p ( a n y , j , r )
i f ( i < j ) s w a p( a n y , i + + , j ) ;
}
i f ( i ! = r ) s w a p ( a n y , i , r ) ;
r e t u r n i ;
I I p e m o v e d t o r
i < j ) i H ; I I u s e s u p p l i e d c
> = 0 ) j - -; I I u s e s u p p l i e d c
I I u se s u p p l i e d s
I I u s e s u p p l i e d s
Page 43
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 43/51
Note that indexing of any is not possible in parti tion because of its
void *. But once its value is passed to the function cmpor swap,the fo
pointer parameter there can be used normally.
With these modifications, the generic quicksort can sort arbitrary a
when given appropriately supplied 'Comparison and swap functions. T
integer arrays, the following set of functions can be defined:
void intswitch(int a[], int i, int j)
{ int s = a[i] i a[i] = a[j] i a[ j] = Si
The two different comparison functions cmp_biggerand cmp_smaller con
to the type CMPIN, and intswi tch matches the type SWAPIN. Now sortinbe done with
II in increasing order
quicksort (a, 0, 5, reinterpret_cast< CMP_FN>(cmp_bigger) ,
reinterpret_cast< SWAP_FN>(intswitch))i
II in decreasing orderquick sort (a, 0, 5 , reinterpret_cast< CMP_FN>(cmp_smaller),
reinterpret_cast< SWAP_FN>(intswitch))i
It is also a simple matter to convert the text-line sorting program in
tion 4.7to use the generic quick sort. For this purpose, the following f unc
are needed:
int keycmp(TextLines *tl, int i, int j)
extern SortKey sortkeYiTextLines& txtob j= *tli
return ( sortk ey.lineCompare(*txtobj[i], *txtob j[j]) )i
void lineswap(TextLines *tl, int i, int j)
tl->swap(i,j)i
Page 44
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 44/51
Again, the two functions are written to match the types CM P]N and SWAP
information available from the arbqsort. h header file. With these f uncti
just use
quicksort (&txtobj , 0, txtobj.length()-l,
reinterpret_cast< CMP _FN >(k eycmp),
reinterpret_cast< SWAP_ FN >(lineswap));
to sort the TextLines object txtob j. Note that here we are sorting text l
encapsulat ed in an objec t with the same generic quicksort f unction, which dri
horne the point of handling data of arbitrary type.
The qsort library function «stdlib. h» implements quick sort for an
bitrary array with elements stored in consecutive memory locations.
quicksort defined in this section does not mak e assumptions on how the
ments to be sorted are stored. Clearly, the basic sorting mechanism is in pl
and will remain unchanged. The header arbqsort. h provides the interf acclient filesof the generalized sorting facility.The application ofthis mechan
in a new area is simply a matter of providing the appropriate comparison
swap functions.
Standard C++ supplies a set of predefined generic functions (incl
<algori thm» that can be used with generic container classes. The generic fu
tions take functional arguments to perform tasks. The header <functiona
supplies a variety of functions ready to use in such applications. These top
are covered in Chapter 11.
We have already seen some uses of the operator newfor dynamic stor
allocation. In this section, let's consider how dynamic storage is applied
relation to arrays and pointers.
Static allocation of two-dimensional arrays is very simple to code. But
syntax for dynamic allocation does not allow direct two-dimensional notatio
Thus, codes such as
are not possible. However, enough consecutive cells f rom free storage
accommodate all elements of a two-dimensional array and can be fabrica
into the desired array structure.
Page 45
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 45/51
The function dyn_2d returns a double** that can be used as
dimensional double array:
double** dyn_2d(int m, int n)
{ double* arr = new double[m*n];
double** a = new double*[m];
f or ( int i=O ; i < m ; i++ ){ a[i] = arr + i*n;
f or (int j=O ; j < n ; j++
a[i] [j] = 0.0;
I I allocate data cells
II allocate pointer cells
II initializeII init m row pointers
II init array cells
II use as two-dimensional
Enough storage for all consecutive data cells is allocated. In addition, s
for pointer cells for each row is allocated. The array and pointer cells ar
initialized before the array name is returned. An overloaded version c
take care of freeing the storage properly:
void dyn_2d(double** a)
delete [] *a;
delete [] a;
II free data cells
II free pointer cells
Let's consider the representation of days in a month. One way to do th
use short integers f or the individual dates, an array of dates for each wee
an array of pointers to the individual week s as a structure for the month
a few typedefs, we can define a class Month to create any monthly calen
I I I I I I I Month.h
#include <iostream>
using std: :ostream;
class Month
{ public:
typedef short Date;
typedef Date *Week; II Week is short *
enum Day {SUN=O,MON,TUE, WED,THU, F R I , SAT};
Month(Date ndays, enum Day firstday);
void display(ostream& out) const;
-Month () ;
private:
Week *month; II internal representation
Page 46
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 46/51
The constructor initializes a month object when given the number of
in the month (ndays) and the day of the week for the first day of the mon
Month::Month(Date ndays, enum Day firstday)
{ Week w[7], Wk i II maximum6 weeksshort i=Oi
Day daYi
wk = w[i] = new Date[7]i
f or (day=SUNi day < firstday
I
day=static_cast< Day >(day+
I
{ *wk++= O i }
f or (Date d = 1 d <= ndays d++)
{ *wk tt = di
if (day == SAT)
( wk = w[++i] = new(Date[7]) i day=SUNi }else day = Day(day+l) i
}
while ( day != SUN)
{ *wk++ = Oiday = Day( (day+l)%7 ) i }
month = new(Week [i+2])i
for (short j=Oi j <= ii j++)
month[ j] =W[j]i
month[i+l] = NULLi II NULLptr terminator
I
I
For each week , seven Dates are allocated (lines 1 and 4) to record the da
the week where pointers returned by new are automatically cast to type
(short *). Days unused in the first and last week are assigned zero (li
and 5). The dates are filled in by the f or loop (line 3). Note that arithm
results involving enumvariables are cast properly (lines 2 and 5).
The automatic array wrecords the weeks created. A dynamic array m
is allocated (line 6) / and the entries of ware copied into the data me
month. Note that month is terminated by a NULLpointer. Figure 4.9 illust
the organization of month.
To establish a Monthobject, use something like
Here the class scope notation is used to specify an enumconstant defined i
Monthclass (In Section 6 7/ displaying a monthly calendar is again consider
Page 47
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 47/51
168 C hap te r 4 A RR AYS, POIN TERS, A ND GEN ER IC C OD E
Figure 4.9 THE ORGANIZATION OF Month WITH POINTERS
m o n t h • . wk [O] • . 0 0 1 2 3 4 5
wk[l] - - - - - - - - -wk [2]
~
6 7 8 9 1 0 1 1 1 2
1 3 1 4 1 5 1 6 1 7 1 8 1 9
The array and the pointer are closely related constructs that help store
manipulate data of any given type. Their mastery is essential for the low-l
coding that is required of you. Such details should be encapsulated by ob
when possible so that other parts of the program can ignore them.
An array stores elements of the same type in consecutive memory locati
The array name is a constant pointer to the first array cell. A two-dimension
array is actually a one-dimensional array whose elements are pointers to
dimensional arrays of the same length. This scheme can be generalized
arrays of higher dimensions. Arrays allocated at compile time have fixed m
imum dimensions. Arrays whose dimensions are known only at run time
be allocated dynamically.
The vector template supplies an attractive alternative to basic array
vector is not limited to a fixed size and can be subscripted just like arrays.
sides, vector offers many useful operations such as size (), insert (), eras
pushJ>ack ( ) , and popJ>ack ( ) .
A pointer provides the ability to manipulate addresses and supplies a
of indirection to data or function access. The unary address-of operator &
be applied to any memory-based variable, class object, or array elemen
obtain a pointer. The unary value-of operator * is applied to a pointer,
to access the value stored at that memory address. Furthermore, the nota
*ptr can be used on the left-hand side of an assignment to store a new v
at that location. Hence, the combination *ptr can be thought of and use
Page 48
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 48/51
Page 49
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 49/51
5. Consider the SortKey class. In practice, there is a need for a composite
k ey consisting of a primary key, a secondary key, and so on. When two
are compared under a composite key, the primary key is applied firs
secondary key is applied only if the two items are equal under the pri
key and so on. Define a CompsitKeyclass, and use it in a sorting program
allows multiple sort keys. (Hint : A CompositKeycontains several SortKe
6. Does the C++ compiler on your computer allow you to increment a v
pointer? If it does, give a good reason why you should not use it.
7. Is it possible to pass a void * actual argument to, say, an int * form
rameter in a function call? If this is not possible, can you specify two di
ways to make such a call by explicit casting? Show your solution with a
working-code examples. (Hint : Cast the argument or the function.)
8. Consider references to pointers. Is there anything wrong with the f ollocode? Why? If there is a problem, how do you fix it?
int a = 5 6;
int*& ptr_ref = &a;
int i;
int & j i;
int&* ptrl = &j;
int* ptr2 = & j;
10. Modify the quicksort routine to remove duplicate entries in the input
The routine should return the length of the final sorted array, which m
shorter than the given array before sorting. (H int: parti tion should r
positions of duplicate entries.)
11. Consider the address-of operator &.Listthe type of quantities to which it c
be applied. Also consider the value-of operator *. List the type of quantit
which it cannot be applied.
12. Discuss the dif ferences and equivalence of the following two notations. In
situations are these notations interchangeable?
type x [] i and type *x;
13. Discuss the differences and similarities of a two-dimensional array an
array of pointers.
Page 50
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 50/51
14. In a class, is it possible to define two instance f unctions whose signatures d
only in the const declaration for the host ob ject?If yes, can you give an exam
that has some practical use?
15. If a class Xyzhas no default constructor, can you declare an array, a vec
with Xyzcells? Why?
16. Write a test program that inserts instances of class Abcinto an empty vec
making it grow. Detect how many Abccopy and destructor calls are mad
the vector grows. What happens if you reserve a number of entries for
vector before running the same experiment?
17. Consider the destructor of TextLines. It deletes all strings kept on line. Is
correct? How can the class be certain that the strings have been allocated
new?
18. Write a simple class Matrix with double entries. Support the following p
lic operations: (a) to create a matrix, given dimensions m and n, and a t
dimensional array of entries; (b) to delete any rows or columns; (c) to in
change any rows or columns; and (d) to display the matrix.
19. Write a quadruple-precision integer class with arithmetic operations +,
and / and then display it. ( H in t: Use an array.)
20. Write a function toEach that takes an array of arbitrary data items and appa supplied unary f unction to each value stored in the array. For example, it
be used to increment each value by 1.
Page 51
8/8/2019 Standard C++ with Object-Oriented Programming BOOK Ch 4
http://slidepdf.com/reader/full/standard-c-with-object-oriented-programming-book-ch-4 51/51
While a plethora of books is used to teach the C++ programming course, many are
technical reference books, which generally don't include examples and exercises. Wang's text
treats C++ as a tool for bridging real-world application, addressing basic theoretical concepts of
object-oriented programming. The material is organized and presented in a simple, concise, andea.sy-to-follow manner. Wang has developed interesting exam~s and challenging exercises that
remforce the text's hands-on approach. '",
This new edition:
• Features the new ANSI C++ standard
• Includes content on the Standard Template Library
• Provjdes content on web applications and how C++ can be applied to them
• Uses a hands-on approach to programming by encouraging wrili!l&,of interesting
prograf f is'e<1rly in the text "~'~"
• Features a p'rif i.1e~(Chapters 1and 2) on essential components of C++,~~rtd
object-based progf ~m±ng" ~*~ \ > , '
\"