standard c++ with object-oriented programming book ch 4

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-Dimen sional 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 

Upload: mrsmohmed

Post on 10-Apr-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

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 

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

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

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

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 &.

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

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.

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

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

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

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.

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]

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

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"

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 } };

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 ( ) ;

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 >

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 ;

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

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

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

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.

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

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 ) ;

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

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

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 )

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

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

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

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

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

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.

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;

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.

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

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) ( );

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

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 ' ;

}

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

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.

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

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

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.

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

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

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

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

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.

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.

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" ~*~ \ > , '

 \"