`
`STEPHEN C. DEWHURST
`
`KATHY T STARK
`
`EEEEEEEEEEEEEEEEEEEEEEE ES
`
`Page 1 of 26
`
`FORD 1112
`
`Page 1 of 26
`
`FORD 1112
`
`
`
`
`
`STEPHEN C. DEWHURST
`KATHY T STARK
`
`This book is written for students and professional programmers who want to
`know more about the object—oriented programming language, C+ +. It is
`helpful if the reader has a strong grasp of the C programming language.
`The authors introduce the features of C+ +, and also describe the modern
`programming paradigms of data abstraction and object—oriented programming.
`
`There are a number of unique features:
`
`0 An overall presentation that encourages the reader to think in new ways
`about the process of programming;
`
`0 A detailed tutorial on the modern programming paradigms of data
`abstraction and object—oriented programming, plus sections on how to apply
`these paradigms;
`
`0 An entire chapter on inheritance;
`
`0 A discussion of code reuse for increased program correctness and
`productivity;
`
`0 A “How —To” section for creating libraries.
`
`For students, there are end—of—chapter exercises. Solved exercises are listed in
`an appendix.
`
`PRENTICE HALL, Englewood Cliffs, N.J. 07632
`
`ISBN El-1.3-?E3‘l5I=-3
`
`7
`
`Page 2 of 26
`
`FORD 1112
`
`Page 2 of 26
`
`FORD 1112
`
`
`
`L
`
`1
`
`*7
`
`1
`
`1
`
`1
`
`M
`
`1
`
`_____V"___,______«_»__W_M_W___W_
`
`PROGRAMMI
`
`GIN
`
`C++
`
`Stephen C. Dewhurst - Kathy T. Stark
`AT&T Bell Laboratories
`
`Summit, New Jersey
`
`3
`
`Prentice Hall, Englewaod Clzfls, New Jersey 07632
`
`Page 3 of 26
`
`FORD 1112
`
`Page 3 of 26
`
`FORD 1112
`
`
`
`Library of Congress Cataloging-in-Publication Data
`Dewhurst, Stephen C.
`Programming in C++.
`(Prentice Hall software series)
`Bibliography: p,
`Includes index.
`I. Stark,
`1. C++ (Computer program language)
`Kathy T.
`II. Title.
`III. Title: Programming in C
`plus plus.
`IV. Series: Prentice—Hall software series.
`QA7o.73.C153D49
`1989
`0()5.l3"3
`89-8391
`ISBN 0137231563
`
`Editorial/production supervision: Karen Skrable Fongang
`Cover design: Lundgren Graphics, Ltd.
`Manufacturing buyer: Robert Anderson
`
`UNlX® is a registered trademark of AT&T.
`
`Prentice Hall Software Series, Brian W. Kemighan, Advisor
`
`
`
`Copyright © 1989 by AT&T Bell Laboratories, Inc.
`Published by Prentice—I-lall, Inc.
`A Division of Simon & Schuster
`Englewood Cliffs, New Jersey 07632
`
`The publisher offers discounts on this book when ordered in bulk
`quantities. For more information write:
`Special Sales/College Marketing
`Prentice—l-Iall, Inc.
`College Technical and Reference Division
`Englewood Cliffs, NJ 07632
`
`All rights reserved. No pan of this book may be
`reproduced. in any form or by any means,
`without permission in writing from the publisher.
`
`Printed in the United States of America
`
`1098765
`
`ISBN El-L3-7231.51-3-3
`
`Prentice—Hall International (UK) Limited, London
`Prentice—Hall of Australia Pty. Limited, Sydney
`Prentice—I-Iall Canada Inc., Toronto
`Prentice—Hall Hispanoamericana, S.A., Mexico
`Prentice—I-lall of India" Private Limited, New Delhi
`Prentice—Hall of Japan, Inc, Tokyo
`Simon & Schuster Asia Pte. Ltd., Singapore
`Editora Prentice—l-{all do Brasil, Ltda., Rio de Janeiro
`
`Page 4 of 26
`
`FORD 1112
`
`Page 4 of 26
`
`FORD 1112
`
`
`
`CHAPTER 1: Data Types and Operations
`
`The C++ type system consists of basic language—defined types, user-
`defined class types, and types that can be derived from the basic and class
`types. The language provides operations and standard conversions for the
`built—in types. Class types can also have operations and conversions defined
`for them, thus allowing classes to be used as consistent extensions of the
`predefined type system.
`The built—in data types in C++ can be interpreted as abstract concepts,
`such as numbers or boolean values, or according to their representation in
`the computer as a sequence of bits. The interpretation depends on the
`operations used to manipulate the values of the different types. The arith-
`metic and logical operators give results that preserve the mathematical and
`logical interpretations of the types. Other operators give results that depend
`on and reveal the bit representation.
`
`1.1 Numeric Types
`
`C++ has both integer and floating point numeric types. The language
`provides arithmetic operators that are overloaded to work with both integer
`and floating point values, and defines conversions among the numeric types.
`Overloaded operators are those operators for which the same symbol
`represents more than one distinct
`implementation of an operation. The
`numeric types, when used with arithmetic operators, are interpreted as
`representations of numbers.
`The following program does a calculation using numeric variables and
`values with arithmetic operators. To represent
`integers int values are
`used, and double floating point values are used to represent real numbers.
`
`
`
`
`
`e;
`en
`
`<3:
`
`\
`
`.%.§is \\\\§<2:§§.i
`
`.
`
`.1
`
`Page 5 of 26
`
`FORD 1112
`
`Page 5 of 26
`
`FORD 1112
`
`
`
`8
`
`DATA TYPES AND OPERATIONS
`
`CHAPTER 1
`
`#include <stdio.h>
`
`main()
`/*
`
`{
`
`Distance of a falling object from the point of its
`release at each of the first 10 seconds of its fall,
`in meters
`
`const double g
`
`9.80;
`
`// acceleration from gravity
`
`{
`t++ )
`for( int t = 1; t <= 10;
`double distance =
`g * t * t / 2;
`printf( "\t%2d %7.2f\n", t, distance );
`
`The program prints out the distance an object has fallen at each of the first
`ten seconds after being dropped:
`4.90
`19.60
`44.10
`78.40
`122.50
`176.40
`240.10
`313.60
`396.90
`490.00
`
`O|.0C0\30\U1J>(.;Jl\)}—‘
`
`|—‘
`
`The expression calculating the distance mixes double and int type
`operands. The result is a double value that is stored in the double vari-
`able distance.
`
`double distance =
`
`g * t * t / 2;
`
`Although both t and 2 have type int, the calculation is done completely
`with floating point operations. Because g has type double, and the multi-
`plications and division group left to right, each operator in the calculation
`has at least one double operand that forces the conversion of the int
`operand to match it.
`The arithmetic operators are overloaded for the numeric types. The
`types of the operands determine whether an integer or floating point opera-
`tion is done.
`If the expression is changed so that the operations are done in
`a different order, the types of some of the operations may also change.
`
`
`
`Page 6 of 26
`
`FORD 1112
`
`Page 6 of 26
`
`FORD 1112
`
`
`
`SECTION 1.1
`
`NUMERIC TYPES
`
`9
`
`distance = g *
`
`( t * t / 2 );
`
`With parentheses forcing the grouping of the integer operands, there is an
`integer multiplication of t by t producing an int result. The division is
`also applied to int operands. The integer division has an int type result;
`when t is odd the fractional part of the result is lost, and this calculation
`produces different results from the previous one with floating point opera-
`tions. Using a floating point literal for the divisor forces the operation to be
`floating point division, and the result returns to the previous accuracy.
`
`distance = g *
`
`( t * t / 2.0 );
`
`For an overloaded operator, the types of the operands affect which imple-
`mentation of the operator is used to perform the operation.
`
`The arithmetic operators are defined to work for operands of several
`numeric types. The unary operators are increment ++, decrement ——, nega-
`tion —, and no—op +. The binary arithmetic operators are multiplication *,
`division /, addition +, and subtraction —.
`In addition, the remainder opera-
`tor % works only on integer operands.
`The increment and decrement operators have the side effect of changing
`the value of the object that is their operand. They can be used in either pre-
`fix or postfix form with different results.
`In the prefix form, the result of
`the expression is that of the object after it was incremented or decremented.
`In the postfix form, the expression value is that of the object before it is
`changed. Other arithmetic operators do not change the value of their
`operands.
`Unary operators have higher precedence than binary operators. The mul-
`tiplicative binary operators *, / , and % have higher precedence than the ad-
`ditive operators + and ~.
`
`The integer types are char, short, int, and long. Each type can
`
`represent at least the range of values as the previous type on the list, so
`each can be thought of as larger or equal in size to the preceding type. The
`integer types come in both signed and unsigned versions.
`In declara-
`tions, short, int, and long type specifiers mean the signed versions
`of these types unless unsigned is explicitly specified. When different
`types of integer operands are combined in an expression, they are converted
`to be the same type. Operands of type char and short are always con~
`verted at least to int. Other conversions are always to the larger of the
`operand types. Conversions are only made to the unsigned version of a
`type if one operand type is unsigned and larger or equal in size to the
`other operand type.
`
`
`
`FORD 1112
`
`
`
`Page 7 of 26
`
`Page 7 of 26
`
`FORD 1112
`
`
`
`10
`
`DATA TYPES AND OPERATIONS
`
`CHAPTER I
`
`types are float, double, and long double.
`The floating point
`Each type can represent at least the set of values of the previous type on the
`list, so each can be thought of as containing the preceding type. When dif-
`ferent floating point types are combined as operands in an arithmetic ex-
`pression, the smal1er—sized operand is converted to the same type as the oth-
`er operand. When floating point and integer operands are combined, the in-
`teger is converted to the same type as the floating point operand.
`
`Any numeric value can be assigned to an object of any other numeric
`type, in which case the value is converted to the type on the left—hand side
`of the assignment.
`
`double d;
`d = 42;
`
`The conversion may result in loss of part of the value.
`int i;
`i = 3.1415;
`char c;
`c = 777;
`
`In the above, i is given the value 3. The value 777 is probably too large
`to be represented in a char, so the value of c after the assignment depends
`on how a particular implementation does the conversion from the larger— to
`smaller—sized integer type.
`
`Conversion operators, or casts, can be used for explicit conversions. For
`example, in the following, the int value of count is explicitly converted
`to double.
`
`12
`
`int count = 1066, total = 1337;
`double ratio;
`
`ratio = double( count
`
`)
`
`/ total;
`
`This example uses a function—ca1l style cast:
`
`double( count
`
`)
`
`An alternative form of the same cast operation is:
`( double )count
`
`The function—call form is usually considered the clearer style in simple
`conversion expressions.
`
`Numeric values can be directly represented in a program as numeric
`
`
`
`Page 8 of 26
`
`FORD 1112
`
`Page 8 of 26
`
`FORD 1112
`
`
`
`SECTION 1.1
`
`NUMERIC TYPES
`
`11
`
`literals. Floating point literals may have a decimal point and a fractional
`part, and also an exponent:
`9.80
`0.98el
`98e—l
`
`These literals all represent the same Value and have type double. For
`values of different floating point types, the suffix L or 1 indicates long
`double, and F or f indicates float.
`
`0.98e1L
`9.80f
`
`Integer literals have type int unless their value is too large or their type
`is indicated with a suffix. A literal value too large to be represented as an
`int may have type long. A suffix L or 1 indicates a long, and U or u
`indicates unsigned. These suffixes may be combined, for example:
`l642UL
`
`An octal literal is indicated with a 0 first digit:
`0777
`
`A hexadecimal literal is indicated with a leading Ox or OX:
`Oxlff
`
`Numeric values may also be represented symbolically by using a const
`with an initializing value.
`
`const double g = 9.80;
`
`Because the const indicates that the value of g cannot be changed, the
`identifier always represents its value 9 . 80.
`Integer values may also be represented symbolically by members of
`enum lists.
`If not otherwise initialized, the enum members have successive
`
`int Values, with the first one having the value 0.
`
`enum { mon,
`
`tues, wed,
`
`thur, fri, sat, sun };
`
`Here, f ri has the value 4. When enum members are explicitly initialized,
`uninitialized members of the list have values that are one more than the pre-
`vious value on the list.
`
`enum { mon = 1,
`
`tues, wed,
`
`thur, fri, sat = -1,
`
`sun };
`
`In this case, the value of fri is 5, and the value of sun is 0.
`
`il.l
`
`lIiAlI.ll l
`
` The character set is represented by integer values that can be contained
`
`Page 9 of 26
`
`FORD 1112
`
`Page 9 of 26
`
`FORD 1112
`
`
`
`
`
`
`
`
`
`12
`
`DATA TYPES AND OPERATIONS
`
`CHAPTER 1
`
`in a char data type. Character literals, which are characters or escape se-
`quences in single quotes, provide a convenient representation of character
`values:
`
`char digit = '9’;
`char w = ’w’;
`char newline = ’\n’;
`char tab = ’\t’;
`char null = ’\O’;
`
`The character values are always positive, even when they are contained in a
`signed char. They can be used as integer operands in expressions:
`int value = digit - '0’;
`
`Useful calculations on character values usually assume certain standard
`character sets, such as ASCII or EBCDIC.
`
`1.2 Scalar Types with Relational and Logical Operators
`There is no boolean type in C++. Scalar types, like integers, work as
`boolean with zero representing the value FALSE and any nonzero value
`representing TRUE. Pointers are also scalar types and are described later in
`this chapter. The relational operators are used to compare values and return
`TRUE or FALSE in the form of an integer value of 1 or O. The logical
`operators work on scalar operands interpreted as TRUE or FALSE and like-
`wise return 1 or 0.
`
`Relational operators produce int results of either 1 or 0. The example
`in the previous section calculating the distance traveled during a fall usesia
`relational expression to control the loop.
`
`for( int t = 1; t <= 10;
`// etc.
`
`t++ )
`
`{
`
`}
`
`To highlight the control condition, we will rewrite the for loop as an
`equivalent while loop.
`int t = 1;
`
`
`
`FORD 1112
`
`
`
`Page 10 of 26
`
`while( t <= 10 )
`// etc.
`t++;
`
`{
`
`}
`
`The loop body executes as long as the condition t <= 10 does not evalu-
`
`Page 10 of 26
`
`FORD 1112
`
`
`
`
`
`
`
`
`
`
`
`SECTION 1.2
`
`SCALAR TYPES WITH RELATIONAL AND LOGICAL OPERATORS
`
`13
`
`ate to O. The expression evaluates to 1 as long as t is less than or equal to
`10 so the loop executes for values of t from 1 to 10.
`The relational operators are less than <, greater than >, less than or equal
`to <= and greater than or equal to >=. There are also the equality operators
`equal to == and not equal to !=. These operators are overloaded for in-
`teger and floating point, as well as pointer operands, but always produce an
`int result of 1 or 0.
`
`Because any nonzero value represents TRUE, any expression can serve
`as a condition, not just those that evaluate to 1 or O. For example:
`int t = 11;
`while( --t )
`// etc.
`
`{
`
`}
`
`The loop body executes for values of t from 10 to 1.
`
`The logical operators are AND &&, OR I I, and NOT !. An expression
`with the unary operator
`! evaluates to 0 if its operand is nonzero and 1
`otherwise. For example, the following sets a previously zero valued vari-
`able:
`
`// i.e. if( p == 0
`if( !p )
`p = get_a_val();
`
`)
`
`I evaluate to 0 if both operands are 0 and 1 otherwise.
`expressions using I
`In the following example, the function error is called only if the value of
`x is not in the range 0 to 10.
`
`if(!(x>=0&&x<=10))
`error("va1ue outside range");
`
`II x > 10 )
`if( x < 0
`error("value outside range");
`
` An && expression evaluates to 1 if both operands are nonzero and 0 other-
`wise. The following checks the same condition as the previous example us-
`
`ing a different logical expression:
`
`
`
`The first expression is preferable to the second because it is easier to under—
`stand.
`
`
`
`
`
`
`is evaluated only if needed to deter-
`I
`The second operand of && and I
`mine the result of the expression.
`If the first operand of an I
`I expression
`evaluates to nonzero, the result is 1 regardless of the value of the second
`operand. Likewise, if the first operand of an && expression evaluates to O,
`
`
`
`
`
`
`
`Page 11 of 26
`
`FORD 1112
`
`Page 11 of 26
`
`FORD 1112
`
`
`
`
`
`14
`
`DATA TYPES AND OPERATIONS
`
`the second operand is not evaluated, and the result of the expression is
`For example, in the following, if b has the value 0, the equality expressio
`is not evaluated and the division subexpression will likewise be bypassed.
`
`if( b && a/b == c )
`// etc.
`
`{
`
`}
`
`The use of && checks that b is not 0 and thus avoids the possibility of a T
`division by 0.
`
`\
`
`
`
`1.3 Nonabstract Operations
`
`C++ has a number of operations that allow a programmer to bypass
`abstract interpretations of types and get at their machine representation.
`Integer types are implemented on a computer as bit sequences of dif-
`ferent lengths. When integers are used with arithmetic, relational, or logical
`operators, their values are interpreted abstractly as numbers, or as TRUE or
`FALSE, and the details of the bit representation can be ignored by the pro-
`grammer. Sometimes the programmer wants to deal with the bits, however.
`Below is a string hash function originated by Peter Weinberger. A hash
`function calculates a numeric value from a character string and is used to
`
`determine a storage location for information keyed on the string. The
`parameter is a pointer to a sequence of characters that are used as numeric
`values in the calculation. The variable hash is manipulated as a sequence
`of 32 bits until it is used as a numeric value in taking the remainder of its
`
`division by prime.
`int
`
`{
`hashpjw( char *s )
`const prime = 211;
`unsigned hash = 0, g;
`
`{
`for( char *p = s; *p ; p++ >
`hash = ( hash << 4
`) + *p;
`// assumes 32 bit int size
`if( g = hash & Oxf0O0OO00 )
`hash “= g >> 24;
`hash “= g;
`
`{
`
`}
`
`} r
`
`eturn hash % prime;
`
`
`
`Page 12 of 26
`
`FORD 1112
`
`Page 12 of 26
`
`FORD 1112
`
`
`
`SECTION 1.4
`
`USER—DEFINED TYPES
`
`15
`
`The bitwise operators used above are left shift <<, right shift >>, bitwise
`AND &, and bitwise exclusive OR “. Bitwise inclusive OR | and the
`unary bitwise complement ~ are also available.
`
`The A operator is used in the example in the form of an assignment
`operator "=. The expression
`
`hash “= g;
`
`is equivalent to
`
`hash = hash A g;
`
`The binary operators *, /, %, +, —, <<, >>, &, ", and I can all be com-
`bined with assignment in the same way.
`
`The sizeof operator gives the number of chars used to represent a
`type. For example the result of
`
`sizeof( int )
`
`is the number of bytes used to represent an int. The value of
`
`sizeof( char )
`
`is always 1. When the operand is an expression instead of a type, the result
`is the size of the type of the expression. A major use of this operator,
`determining of space needed for dynamic creation of an object, has been in-
`corporated into the C++ memory management operators new and delete.
`With these operators taking care of the mechanics of space allocation, a pro-
`grammer will rarely need to know the size of a type representation.
`
`1.4 User-Defined Types
`
`Class types can be defined by the user to extend the basic C++ type sys-
`tem. Operations and conversions can be defined for class types so that they
`can be used in combination with other types.
`The following is a program that calculates the voltage of an AC electri-
`cal circuit containing a conductor, a resistor and a capacitor using the for-
`mula Z = R + j(oL + 1 / (jc0C) for impedance and V = Z] for voltage. The
`voltage, current, and impedance of AC circuits have two components that
`are represented by the real and imaginary parts of a complex number.
`There is no language-defined complex number type in C++. The program
`
`uses a user—defined class type to represent complex number values.
`
`Page 13 of 26
`
`FORD 1112
`
`Page 13 of 26
`
`FORD 1112
`
`
`
`DATA TYPES AND OPERATIONS
`
`#include "complex.h"
`
`main()
`/*
`
`{
`
`calculate voltage of an AC circuit
`
`*/
`
`// imaginary 1
`1 );
`const complex j( 0,
`const double pi = 3.1415926535897931;
`
`double
`
`Z = R + j
`V = Z * I;
`V
`
`.print();
`
`}
`
`in henries
`// inductance,
`in ohms
`// resistance,
`in farads
`// capacitance,
`frequency in hertz
`* freq;
`frequency in radians/sec
`
`current
`
`impedance
`voltage
`
`* omega * L + 1/( j
`
`* omega * C );
`
`The output of the program is
`( 60000.00, 134.13 )
`The header file complex.h contains the definition of the class type
`complex, that implements the mathematical notion of complex numbers.
`An abridged Version of class complex is used for the example.
`
`class complex {
`double re,
`
`im;
`
`public:
`complex( double r
`{ re = r;
`im
`void print();
`x operator +( complex, complex );
`friend comple
`r *( complex, complex );
`friend complex operato
`( complex, complex );
`friend complex operator /
`
`};
`
`The class definition contains the declaration
`declarat
`ion of friend functions, which have s
`
`s of members as well as the
`pecial access to members of
`
`Page 14 of 26
`
`FORD 1112
`
`Page 14 of 26
`
`FORD 1112
`
`
`
`
`
`
`
`SECTION 1.4
`
`USER-DEFINED TYPES
`
`17
`
`the class. The members declared after the public label are accessible
`without restriction, whereas the private members, re and im, can only be
`accessed by member and friend functions. The data member representation
`of complex is hidden in the private part of the class, and so the type is
`only usable through the publicly available functions.
`
`The member function with the same name as the class is a constructor.
`The constructor is used to create and initialize complex objects, or to con-
`vert values of other types to the class type. This constructor is declared
`with default argument values, so it can be invoked with zero, one, or two
`arguments, with the default arguments being filled in when needed. The de-
`claration
`
`const complex j( 0,
`
`l );
`
`has an initializer that provides both constructor arguments, with the real and
`imaginary parts of j being set to O and 1, respectively. The declaration
`
`complex I = 12;
`
`is equivalent to
`
`complex I( 12,
`
`0 );
`
`The default argument fills in O for the argument that sets the imaginary part
`of I. Both Z and V are initialized with the default constructor arguments,
`because no other initial values are indicated in their declarations.
`
`The other functions declared in class complex are defined outside
`the class:
`
`void
`
`{
`complex::print()
`printf("( %5.2f, %5.2f )\n", re,
`
`im );
`
`} c
`
`omplex
`
`{
`operator +( complex al, complex a2 )
`return complex( al.re + a2.re, a1.im + a2.im );
`
`
`}
`
`Page 15 of 26
`
`FORD 1112
`
`Page 15 of 26
`
`FORD 1112
`
`
`
`18
`
`DATA TYPES AND OPERATIONS
`
`complex
`operator *( complex al, complex a2 )
`{
`
`return complex(a1.re * a2.re — al.im * a2.im,
`al.re * a2.im + al.im * a2.re);
`
`complex
`operator /
`{
`
`(complex al, complex a2)
`
`double r = a2.re;
`double i = a2.im;
`double ti;
`/* (tr,ti) */
`double tr;
`
`/* (r,i) */
`
`tr = r
`ti = i
`if (tr
`ti
`
`(1 + ti*ti);
`i *
`tr
`r = al.re;
`i = a1.im;
`
`ti = -i/r;
`tr = r *
`(1 + ti*ti);
`r = ~al.im;
`i — al.re;
`
`} r
`
`eturn complex( (r*ti + i)/tr,
`
`(i*ti — r)/tr );
`
`The member function print is used in the example to print the result-
`ing value of V.
`
`V.print();
`
`the other members of the
`As a member function, print can access all
`class without restriction.
`It formats and prints the re and im members of
`the complex object for which it is called.
`
`friend inside class
`are declared as
`functions
`The operator
`complex. Friend functions are not members of the class, but like member
`functions they are allowed access to private members of a complex object.
`The operator
`functions implement arithmetic operations for complex
`
`Page 16 of 26
`
`FORD 1112
`
`Page 16 of 26
`
`FORD 1112
`
`
`
`SECTION 1.5
`
`POINTERS AND ARRAYS
`
`19
`
`values and allow complex operands in expressions with infix notation.
`
`Z=R+j*omega*L+l/(j*omega*C);
`
`The expression that calculates impedance mixes int, double, and
`complex operands. When an int or double operand is used with a
`complex one,
`the constructor is automatically applied to convert
`the
`operand to complex before the operator
`function is called with the
`operands as arguments. Predefined conversions between built—in types are
`applied to get the correct constructor argument types, so the single construc-
`tor
`serves
`to convert both int
`and double operands. When the
`complex constructor is used in conversions, the default value is filled in
`
`as the second argument.
`
`With the hidden representation and user—defined operators ‘and conver-
`sions, class complex is an abstract numeric type that combines natural-
`ly with the predefined numeric types.
`
`1.5 Pointers and Arrays
`
`Pointers and arrays are derived from other types. Pointer types represent
`the addresses of objects of another type. They are used to keep track of
`dynamically allocated objects, for flexibility in data structures, and with
`pointer arithmetic operators to access elements of arrays. Array types
`represent a sequence of elements of a particular type and have many uses as
`aggregate data structures. One standard use of arrays is as strings, which
`are sequences of characters.
`
`Pointer types are indicated by using the type modifier * along with other
`type information in declarations. The same symbol is used for the pointer
`dereference operator, which returns the object being pointed to. The result
`of a dereference can be used for the value of the object or on the left—hand
`side of an assignment.
`
`
`
`int *p;
`int i = 33;
`
`p = &i;
`*p = *p + 1;
`
`// p is a pointer to int
`
`// p set to point to i
`// i set to 34
`
`The & operator returns the address of the object that is its operand. Address
`values have the type pointer—to—object—type.
`The dynamic allocation operator new creates an object having a type in-
`dicated by its operand and returns a pointer to the new object. An object
`
`Page 17 of 26
`
`FORD 1112
`
`Page 17 of 26
`
`FORD 1112
`
`
`
`
`
`20
`
`DATA TYPES AND OPERATIONS
`
`CHAPTER 1
`
`created by new can be destroyed using operator delete, which takes as its
`operand a pointer to the doomed object.
`
`int *p = 0;
`
`if( !p>
`P
`
`new int;
`
`delete p;
`p = O;
`The code fragment above declares a pointer and initializes it to O, which is
`the special null pointer value and an invalid address. The pointer
`is
`checked to see if it has been set, and if not, it is given the address of a new
`ly created object. The object is then deleted, and the pointer is reset to null.
`The combination of pointers, the use of null pointers as flags, and the allo-
`cation and deallocation of objects with operators new and delete are the
`rudiments for building dynamic data structures in C++.
`
`There are no automatic conversions among pointer types, except in limit-
`ed cases in assignment and initialization. There is a special void *
`pointer type that will hold a pointer value of any type. One can think of
`void * as a pointer—to—anything type. Any other pointer type is automati-
`cally converted to match a void * in an assignment or initialization.
`int *ip;
`void *vp = ip;
`double *dp;
`vp = dp;
`ip = (int *)vp; // not a good idea
`
`A void * is only converted to another type of pointer if the programmer
`explicitly requests it with a cast. Such an explicit conversion is risky be-
`cause it bypasses the type checking that ensures that the pointed-to object is
`interpreted in a consistent way. There are automatic conversions among
`pointers to related class types. These are discussed in Chapter 5.
`
`An array is a sequence of contiguously allocated elements of the same
`type. The addresses of the elements in an array can be calculated from
`those of other elements using arithmetic operations overloaded for pointer
`operands. A loop that sequences through the elements of a string demon-
`strates a use of pointer arithmetic:
`
`
`
`Page 18 of 26
`
`FORD 1112
`
`Page 18 of 26
`
`FORD 1112
`
`
`
`SECTION 1.5
`
`POINTERS AND ARRAYS
`
`21
`
`for( char *p = s; *p ; p++ )
`// etc.
`
`{
`
`In this example, s is an array of char, which represents a string. The
`pointer p is initialized to point to the first element in the array and then in-
`cremented to point to successive elements, until one of the elements is O.
`The string is conventionally terminated by a 0 element.
`Both increment ++ and decrement —— operators work on pointer
`operands whose Values are assumed to be the addresses of array elements.
`Increment changes the pointer to refer to the next element in the array, and
`decrement changes it to refer to the previous element.
`The binary operators addition + and subtraction — are defined to work on
`one pointer operand and one integer operand. For subtraction, the integer
`must be the second operand. Again, the pointers are assumed to be the ad-
`dresses of array elements. The results of the operations are addresses of
`other array elements. For example,
`the following addition adjusts p to
`point to the third element past the one it originally pointed to.
`
`p+= 3;
`
`The following subtraction sets p to the second element before the original
`one.
`
`
`
`
`
`
`
`
`
`P-=2;
`
`Subtraction is also defined to work on two pointer operands that are the
`addresses of elements in the same array. The result is an int value that is
`the number of elements between the array locations referred to by the
`pointers.
`
`In an array de-
`An array type is indicated with the type modifier [].
`claration, the braces contain the number of elements in the array. For ex-
`ample
`
`char buffer[lOO];
`
`declares an array of 100 char elements. The name buffer represents
`the address of the first element in the array. This name can be used with
`the pointer arithmetic operations to access the elements of the array. The
`following loop zeros out the elements of buf fer.
`
`i < 100;
`for( int i = 0;
`*( buffer + i ) = O;
`
`i++ )
`
`In the follow-
`A pointer expression can be used to access array elements.
`ing, p is initially set to the address of the first element of buffer and then
`
`
`
`Page 19 of 26
`
`FORD 1112
`
`Page 19 of 26
`
`FORD 1112
`
`
`
`22
`
`DATA TYPES AND OPERATIONS
`
`CHAPTER 1
`
`used to copy the first twenty elements into another array called name.
`char name[2l];
`
`p = buffer;
`i< 20;
`for( i = 0;
`name[i] = *p++;
`The subscript operator [] provides a shorthand expression for the pointer
`operations used to access array elements. The subscript expression
`name[i]
`
`i++ )
`
`is the same as
`
`*(name + i)
`The subscript operator can be used with any pointer operand, not just array
`names. The following sets the location before p to null:
`
`Pl-ll = ’\0’;
`
`The basic representation of a string in C++ is a sequence of character
`values in a char array with a terminating 0 element. String literals pro—
`vide a way of representing such arrays. A string literal is a sequence of
`characters or escape sequences surrounded by double quotes:
`"This is a string literal\n"
`The value of a string literal is a pointer to the first element of a char array
`whose size is one more than the number of characters between the quotes.
`The array elements have the values of the characters followed by the value
`0.
`
`1.6 References
`Reference types establish aliases for objects. They are used as function
`parameter types in order to pass arguments by reference,
`instead of by
`value.
`A reference type is indicated in a declaration by using the modifier & in
`the same way as a pointer modifier. A reference must have an initializer.
`Once the reference is initialized, its use produces the same results as if the
`aliased object were used directly. The major use of references is for param-
`eter types.
`In order to demonstrate how references work, we first show
`them in nonparameter declarations.
`
`
`
`
`
`Page 20 of 26
`
`FORD 1112
`
`Page 20 of 26
`
`FORD 1112
`
`
`
`SECTKJN L6
`
`REFERENCES
`
`23
`
`To establish an alias, the initializer should be the name of an object of
`the type that is referenced.
`
`int i;
`int &ir = i;
`
`This establishes ir as an alias for 1. Assignment to and use of ir pro-
`duces the same results as assignment to and use of i.
`
`// i gets the value 3
`
`ir = 3;
`int j;
`int *ip;
`j = i * ir; // j gets the value 9
`ip = &ir;
`T/
`ip gets the address of i
`
`Once the initializer establishes the object that the reference aliases, it cannot
`be changed.
`If the initializer for the reference is not of the right type, an anonymous
`object is created for which the reference becomes an alias. The initializer is
`converted, and its Value is used to set the Value of the anonymous object.
`double d;
`
`int &ir = d;
`ir = 3.0;
`
`// anonymous int object created
`// d is not changed!
`
`An anonymous object is also created to initialize a reference when the ini-
`tializer is not an object.
`
`int &ir = 3;
`
`// anonymous object gets value 3
`
`A major use of reference type parameters is to allow a function to set the
`value of its actual arguments.
`In this case, references are used to establish
`aliases for the arguments within the function.
`
`void input( int &,
`int a, b, c;
`
`int &,
`
`int & );
`
`input( a, b, C );
`
`// set argument values
`
`Pointer parameters can also be used to change objects external to the func-
`tion, but address and pointer operations are then needed in manipulating ar-
`guments and parameters. Reference parameters that establish aliases pro-
`vide a convenient alternative to pointer arguments.
`Another use of reference parameters is to avoid the overhead of initializ-
`ing parameters with argume