58
Chapter 8 Pointers (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved.

(continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

Embed Size (px)

Citation preview

Page 1: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

Chapter 8Pointers

(continue)

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 2: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.4  Pass-by-Reference with Pointers (cont.) In the function header and in the prototype for a function

that expects a one-dimensional array as an argument, pointer notation may be used.

The compiler does not differentiate between a function that receives a pointer and a function that receives a one-dimensional array.◦ The function must “know” when it’s receiving an array or simply a

single variable which is being passed by reference. When the compiler encounters a function parameter for a

one-dimensional array of the form int b[], the compiler converts the parameter to the pointer notation int *b.◦ Both forms are interchangeable.

Page 3: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers

Many possibilities exist for using (or not using) const with function parameters.

Principle of least privilege ◦ Always give a function enough access to the data in its

parameters to ac-complish its specified task, but no more.

Page 4: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers (cont.) There are four ways to pass a pointer to a function

◦ a nonconstant pointer to nonconstant data ◦ a nonconstant pointer to constant data (Fig. 8.10)◦ a constant pointer to nonconstant data (Fig. 8.11)◦ a constant pointer to constant data (Fig. 8.12)

Each combination provides a different level of access privilege.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 5: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers (cont.) The highest access is granted by a nonconstant pointer

to nonconstant data◦ The data can be modified through the dereferenced pointer, and

the pointer can be modified to point to other data. Such a pointer’s declaration (e.g., int *countPtr)

does not in-clude const.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 6: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers (cont.) A nonconstant pointer to constant data

◦ A pointer that can be modified to point to any data item of the appropriate type, but the data to which it points cannot be modified through that pointer.

Might be used to receive an array argument to a function that will process each array element, but should not be allowed to modify the data.

Any attempt to modify the data in the function results in a compilation error.

Sample declaration: const int *countPtr;

◦ Read from right to left as “countPtr is a pointer to an integer constant.” Figure 8.10 demonstrates the compilation error messages produced

when attempting to compile a function that receives a nonconstant pointer to constant data, then tries to use that pointer to modify the data.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 7: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 8: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers (cont.) A constant pointer to nonconstant data is a pointer that always

points to the same memory location; the data at that location can be modified through the pointer.

An example of such a pointer is an array name, which is a constant pointer to the beginning of the array.

All data in the array can be accessed and changed by using the array name and array subscripting.

A constant pointer to nonconstant data can be used to receive an array as an argument to a function that accesses array elements using array subscript notation.

Pointers that are declared const must be initialized when they’re declared.

If the pointer is a function parameter, it’s initialized with a pointer that’s passed to the function.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 9: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 10: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.5  Using const with Pointers (cont.) The minimum access privilege is granted by a constant pointer to

constant data.◦ Such a pointer always points to the same memory location, and the data

at that location cannot be modified via the pointer.◦ This is how an array should be passed to a function that only reads the

array, using array subscript notation, and does not modify the array. The pro-gram of Fig. 8.12 declares pointer variable ptr to be of

type const int * const (line 13). This declaration is read from right to left as “ptr is a constant

pointer to an integer constant.” The figure shows the error messages generated when an attempt

is made to modify the data to which ptr points and when an attempt is made to modify the address stored in the pointer variable.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 11: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 12: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.6  Selection Sort Using Pass-by-Reference Selection- sort

◦ Easy-to-program, but inefficient, sorting algorithm.◦ The first iteration of the algorithm selects the smallest element

in the array and swaps it with the first element.◦ The second iteration selects the second-smallest element

(which is the smallest element of the remaining elements) and swaps it with the second element.

◦ The algorithm continues until the last iteration selects the second-largest element and swaps it with the second-to-last index, leaving the largest element in the last index.

◦ After the ith iteration, the smallest i items of the array will be sorted into increasing order in the first i elements of the array.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 13: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 14: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 15: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 16: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.6  Selection Sort Using Pass-by-Reference (cont.) Re-member that C++ enforces information hiding between

functions, so function swap does not have access to individual array elements in selectionSort.

Because selectionSort wants swap to have access to the array elements to be swapped, selectionSort passes each of these elements to swap by reference.◦ The address of each array element is passed explicitly.

When swap references *element1Ptr, it’s actually referencing array[ i ] in selectionSort.

When swap references *element2Ptr, it’s actually referencing array[ smallest ] in selectionSort.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 17: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.7  sizeof Operator

The unary operator sizeof determines the size of an array (or of any other data type, variable or constant) in bytes during program compilation.

When applied to the name of an ar-ray, the sizeof operator returns the total number of bytes in the array as a value of type size_t.

When applied to a pointer parameter in a function that receives an array as an argument, the sizeof operator returns the size of the pointer in bytes—not the size of the array.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 18: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 19: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 20: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.7  sizeof Operator (cont.)

The number of elements in an array also can be determined using the results of two sizeof operations.

Consider the following array decla-ration: double realArray[ 22 ];

To determine the number of elements in the array, the following expression (which is evaluated at compile time) can be used:

sizeof realArray / sizeof( realArray[ 0 ] ) The expression determines the number of bytes in array realArray and divides that value by the number of bytes used in memory to store the array’s first element.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 21: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.7  sizeof Operator (cont.)

Figure 8.15 uses sizeof to calculate the number of bytes used to store most of the standard data types.

The output shows that the types double and long double have the same size.◦ Types may have different sizes based on the platform running

the program.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 22: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 23: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 24: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.7  sizeof Operator (cont.)

Operator sizeof can be applied to any expression or type name.

When sizeof is applied to a variable name (which is not an array name) or other expression, the num-ber of bytes used to store the specific type of the expression’s value is returned.

The parentheses used with sizeof are required only if a type name is supplied as its operand.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 25: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 26: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) Assume that array int v[5] has been declared and

that its first element is at memory location 3000. Assume that pointer vPtr has been initialized to point

to v[0] (i.e., the value of vPtr is 3000). Figure 8.16 diagrams this situation for a machine with

four-byte integers.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 27: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 28: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) In conventional arithmetic, the addition 3000 + 2

yields the value 3002.◦ This is normally not the case with pointer arithmetic.◦ When an integer is added to, or subtracted from, a pointer, the

pointer is not simply incremented or decremented by that integer, but by that integer times the size of the object to which the pointer refers.

◦ The number of bytes depends on the object’s data type.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 29: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) Pointer variables pointing to the same array may be

subtracted from one another. For example, if vPtr contains the address 3000 and v2Ptr contains the address 3008, the statement

x = v2Ptr - vPtr; would assign to x the number of array elements from vPtr to v2Ptr—in this case, 2.

Pointer arithmetic is meaningless unless performed on a pointer that points to an array.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 30: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) A pointer can be assigned to another pointer if both

pointers are of the same type. Otherwise, a cast operator (normally a reinterpret_cast; discussed in Section 17.8) must be used to convert the value of the pointer on the right of the assignment to the pointer type on the left of the assignment.◦ Exception to this rule is the pointer to void (i.e., void *).

All pointer types can be assigned to a pointer of type void * without casting.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 31: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) A void * pointer cannot be dereferenced.

◦ The com-piler must know the data type to determine the number of bytes to be dereferenced for a particular pointer—for a pointer to void, this number of bytes cannot be determined from the type.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 32: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.8  Pointer Expressions and Pointer Arithmetic (cont.) Pointers can be compared using equality and relational

operators.◦ Comparisons using relational operators are meaningless unless

the pointers point to members of the same array.◦ Pointer comparisons compare the addresses stored in the

pointers. A common use of pointer comparison is determining

whether a pointer is 0 (i.e., the pointer is a null pointer—it does not point to anything).

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 33: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.9  Relationship Between Pointers and Arrays An array name can be thought of as a constant pointer. Pointers can be used to do any operation involving array

subscripting. Assume the following declarations:

int b[ 5 ]; // create 5-element int array bint *bPtr; // create int pointer bPtr

Because the array name (without a subscript) is a (constant) pointer to the first element of the array, we can set bPtr to the address of the first element in array b with the statement

bPtr = b; // assign address of array b to bPtr equivalent to

bPtr = &b[ 0 ]; // also assigns address of array b to bPtr

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 34: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.9  Relationship Between Pointers and Arrays (cont.) Array element b[ 3 ] can alternatively be referenced

with the pointer expression *( bPtr + 3 )

The 3 in the preceding expression is the offset to the pointer.

This notation is re-ferred to as pointer/offset notation.◦ The parentheses are necessary, because the precedence of * is

higher than that of +.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 35: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.9  Relationship Between Pointers and Arrays (cont.) Just as the array element can be refer-enced with a pointer

expression, the address &b[ 3 ]

can be written with the pointer expression bPtr + 3

The array name (which is implicitly const) can be treated as a pointer and used in pointer arithmetic.

For exam-ple, the expression *( b + 3 )

also refers to the array element b[ 3 ]. In general, all subscripted array expressions can be written

with a pointer and an offset.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 36: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.9  Relationship Between Pointers and Arrays (cont.) Pointers can be subscripted exactly as arrays can. For example, the expression

bPtr[ 1 ] refers to the array element b[ 1 ]; this expression uses

pointer/subscript notation.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 37: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 38: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 39: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 40: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.9  Relationship Between Pointers and Arrays (cont.) Figure 8.18 uses the four notations discussed in this

section for referring to array elements—array subscript notation, pointer/offset notation with the array name as a pointer, pointer subscript notation and pointer/offset notation with a pointer—to accomplish the same task, namely printing the four elements of the integer array b.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 41: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing This section introduces C-style, pointer-based strings. C++’s string class is preferred for use in new

programs, because it eliminates many of the security problems that can be caused by manipulating C strings.

We cover C strings here for a deeper understanding of arrays.

Also, if you work with legacy C++ programs, you may be required to manipulate these pointer-based strings.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 42: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing (cont.) Characters are the fundamental building blocks of C++ source

programs. Character constant

◦ An integer value represented as a character in single quotes.◦ The value of a character constant is the integer value of the character in

the machine’s character set. A string is a series of characters treated as a single unit.

◦ May include letters, digits and various special characters such as +, -, *, /and $.

String literals, or string constants, in C++ are written in double quotation marks

A pointer-based string is an array of characters ending with a null character ('\0').

A string is accessed via a pointer to its first character.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 43: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing (cont.) The value of a string literal is the address of its first character, but

the sizeof a string literal is the length of the string including the terminating null character.

A string literal may be used as an initializer in the declaration of either a character array or a variable of type char *.

String literals have static storage class (they exist for the duration of the program) and may or may not be shared if the same string literal is referenced from multiple locations in a program.

The effect modifying a string literal is undefined; thus, you should always declare a pointer to a string literal as const char *.

When declaring a character array to contain a string, the array must be large enough to store the string and its terminating null character.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 44: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing (cont.) Because a string is an array of characters, we can

access individual characters in a string directly with array subscript notation.

A string can be read into a character array using stream extraction with cin.

The setw stream manipulator can be used to ensure that the string read into word does not exceed the size of the array.◦ Applies only to the next value being input.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 45: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing (cont.) In some cases, it’s desirable to input an entire line of text

into a character array. For this purpose, the cin object provides the member

function getline. Three arguments—a character array in which the line of text

will be stored, a length and a delimiter character. The function stops reading characters when the delimiter

character '\n' is encountered, when the end-of-file indicator is entered or when the number of characters read so far is one less than the length specified in the second argument.

The third argument to cin.getline has '\n' as a default value.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 46: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.10  Pointer-Based String Processing (cont.) A character array representing a null-terminated string

can be output with cout and <<. The characters of the string are output until a

terminating null character is encountered; the null character is not printed.

cin and cout assume that character arrays should be processed as strings terminated by null characters; cin and cout do not provide similar input and output processing capabilities for other array types.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 47: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.11  Arrays of Pointers

Arrays may contain pointers. A common use of such a data structure is to form an array of

pointer-based strings, referred to simply as a string array. Each entry in the array is a string, but in C++ a string is

essentially a pointer to its first character, so each entry in an array of strings is simply a pointer to the first character of a string.

const char * const suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" };◦ An array of four elements.◦ Each element is of type “pointer to char constant data.”

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 48: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 49: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.11  Arrays of Pointers (cont.)

String arrays are commonly used with command-line arguments that are passed to function main when a program begins execution.

Such arguments follow the program name when a program is executed from the command line.

A typical use of command-line arguments is to pass options to a program.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 50: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.12  Function Pointers

A pointer to a function contains the function’s address in memory.

A function’s name is actually the starting address in memory of the code that performs the function’s task.

Pointers to functions can be ◦ Passed to functions◦ Returned from functions◦ Stored in arrays◦ Assigned to other function pointers ◦ Used to call the underlying function

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 51: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.12  Function Pointers (cont.)

To illustrate the use of pointers to functions, Fig. 8.20 modifies the selection sort pro-gram of Fig. 8.13.

Function selectionSort receives a pointer to a function—either function ascending or function descending—as an argument in addition to the integer array to sort and the size of the array.

Functions ascending and descending determine the sorting order.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 52: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 53: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 54: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 55: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 56: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 57: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.12  Function Pointers (cont.)

bool ( *compare )( int, int ) This parameter specifies a pointer to a function.

◦ The keyword bool indicates that the function being pointed to returns a bool value.

◦ The text (*compare) indicates the name of the pointer to the function (the * indicates that parameter compare is a pointer).

◦ The text (int, int) indicates that the function pointed to by compare takes two integer arguments.

◦ Parentheses are needed around *compare to indicate that compare is a pointer to a function.

The corresponding parameter in the function prototype of selectionSort is

bool (*)( int, int )

©1992-2010 by Pearson Education, Inc. All Rights Reserved.

Page 58: (continue) ©1992-2010 by Pearson Education, Inc. All Rights Reserved

8.12  Function Pointers (cont.)

The function passed to selectionSort is called as follows: ( *compare )( work[ smallestOrLargest ], work[ index ] )

Just as a pointer to a variable is dereferenced to access the value of the variable, a pointer to a function is dereferenced to execute the function.

The parentheses around *compare are necessary; otherwise, the * operator would attempt to dereference the value returned from the function call.

Call could have been made without dereferencing the pointer, as in

compare( work[ smallestOrLargest ], work[ index ] ) which uses the pointer directly as the function name.

©1992-2010 by Pearson Education, Inc. All Rights Reserved.