Relationship Between Pointers and Arrays

Arrays and pointers are intimately related in C++ and may be used almost interchangeably. 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 b
int *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

This is equivalent to taking the address of the first element of the array as follows:

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

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. When the pointer points to the beginning of an array, the offset indicates which element of the array should be referenced, and the offset value is identical to the array subscript. The preceding notation is referred to as pointer/offset notation. The parentheses are necessary, because the precedence of * is higher than the precedence of +. Without the parentheses, the above expression would add 3 to the value of *bPtr (i.e., 3 would be added to b[ 0 ], assuming that bPtr points to the beginning of the array). Just as the array element can be referenced with a pointer expression, the address

&b[ 3 ]

can be written with the pointer expression

bPtr + 3

The array name can be treated as a pointer and used in pointer arithmetic. For example, 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. In this case, pointer/offset notation was used with the name of the array as a pointer. Note that the preceding expression does not modify the array name in any way; b still points to the first element in the array.

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.

Remember that an array name is a constant pointer; it always points to the beginning of the array. Thus, the expression

b += 3

causes a compilation error, because it attempts to modify the value of the array name (a constant) with pointer arithmetic.

Common Programming Error 8.14

Although array names are pointers to the beginning of the array and pointers can be modified in arithmetic expressions, array names cannot be modified in arithmetic expressions, because array names are constant pointers.

Good Programming Practice 8.2

For clarity, use array notation instead of pointer notation when manipulating arrays.

Figure 8.20 uses the four notations discussed in this section for referring to array elementsarray subscript notation, pointer/offset notation with the array name as a pointer, pointer subscript notation and pointer/offset notation with a pointerto accomplish the same task, namely printing the four elements of the integer array b.

Figure 8.20. Referencing array elements with the array name and with pointers.

(This item is displayed on pages 428 - 429 in the print version)

 1 // Fig. 8.20: fig08_20.cpp
 2 // Using subscripting and pointer notations with arrays.
 3 #include 
 4 using std::cout;
 5 using std::endl;
 6
 7 int main()
 8 {
 9 int b[] = { 10, 20, 30, 40 }; // create 4-element array b
10 int *bPtr = b; // set bPtr to point to array b
11
12 // output array b using array subscript notation
13 cout << "Array b printed with:

Array subscript notation
";
14
15 for ( int i = 0; i < 4; i++ )
16 cout << "b[" << i << "] = " << b[ i ] << '
';
17
18 // output array b using the array name and pointer/offset notation
19 cout << "
Pointer/offset notation where "
20 << "the pointer is the array name
";
21
22 for ( int offset1 = 0; offset1 < 4; offset1++ )
23 cout << "*(b + " << offset1 << ") = " << *( b + offset1 ) << '
';
24
25 // output array b using bPtr and array subscript notation
26 cout << "
Pointer subscript notation
";
27
28 for ( int j = 0; j < 4; j++ )
29 cout << "bPtr[" << j << "] = " << bPtr[ j ] << '
';
30
31 cout << "
Pointer/offset notation
";
32
33 // output array b using bPtr and pointer/offset notation
34 for ( int offset2 = 0; offset2 < 4; offset2++ )
35 cout << "*(bPtr + " << offset2 << ") = "
36 << *( bPtr + offset2 ) << '
';
37
38 return 0; // indicates successful termination
39 } // end main
 
 Array b printed with:

 Array subscript notation
 b[0] = 10
 b[1] = 20
 b[2] = 30
 b[3] = 40

 Pointer/offset notation where the pointer is the array name
 *(b + 0) = 10
 *(b + 1) = 20
 *(b + 2) = 30
 *(b + 3) = 40

 Pointer subscript notation
 bPtr[0] = 10
 bPtr[1] = 20
 bPtr[2] = 30
 bPtr[3] = 40

 Pointer/offset notation
 *(bPtr + 0) = 10
 *(bPtr + 1) = 20
 *(bPtr + 2) = 30
 *(bPtr + 3) = 40
 

To further illustrate the interchangeability of arrays and pointers, let us look at the two string-copying functionscopy1 and copy2in the program of Fig. 8.21. Both functions copy a string into a character array. After a comparison of the function prototypes for copy1 and copy2, the functions appear identical (because of the interchangeability of arrays and pointers). These functions accomplish the same task, but they are implemented differently.

Figure 8.21. String copying using array notation and pointer notation.

 1 // Fig. 8.21: fig08_21.cpp
 2 // Copying a string using array notation and pointer notation.
 3 #include 
 4 using std::cout;
 5 using std::endl;
 6
 7 void copy1( char *, const char * ); // prototype
 8 void copy2( char *, const char * ); // prototype
 9
10 int main()
11 {
12 char string1[ 10 ];
13 char *string2 = "Hello";
14 char string3[ 10 ];
15 char string4[] = "Good Bye";
16
17 copy1( string1, string2 ); // copy string2 into string1
18 cout << "string1 = " << string1 << endl;
19
20 copy2( string3, string4 ); // copy string4 into string3
21 cout << "string3 = " << string3 << endl;
22 return 0; // indicates successful termination
23 } // end main
24
25 // copy s2 to s1 using array notation 
26 void copy1( char * s1, const char * s2 )
27 {
28 // copying occurs in the for header
29 for ( int i = 0; ( s1[ i ] = s2[ i ] ) != ''; i++ )
30  ; // do nothing in body 
31 } // end function copy1
32
33 // copy s2 to s1 using pointer notation
34 void copy2( char *s1, const char *s2 ) 
35 {
36 // copying occurs in the for header
37 for ( ; ( *s1 = *s2 ) != ''; s1++, s2++ )
38  ; // do nothing in body 
39 } // end function copy2
 
 string1 = Hello
 string3 = Good Bye
 

Function copy1 (lines 2631) uses array subscript notation to copy the string in s2 to the character array s1. The function declares an integer counter variable i to use as the array subscript. The for statement header (line 29) performs the entire copy operationits body is the empty statement. The header specifies that i is initialized to zero and incremented by one on each iteration of the loop. The condition in the for, ( s1[ i ] = s2[ i ] ) != '', performs the copy operation character by character from s2 to s1. When the null character is encountered in s2, it is assigned to s1, and the loop terminates, because the null character is equal to ''. Remember that the value of an assignment statement is the value assigned to its left operand.

Function copy2 (lines 3439) uses pointers and pointer arithmetic to copy the string in s2 to the character array s1. Again, the for statement header (line 37) performs the entire copy operation. The header does not include any variable initialization. As in function copy1, the condition ( *s1 = *s2 ) != '' performs the copy operation. Pointer s2 is dereferenced, and the resulting character is assigned to the dereferenced pointer s1. After the assignment in the condition, the loop increments both pointers, so they point to the next element of array s1 and the next character of string s2, respectively. When the loop encounters the null character in s2, the null character is assigned to the dereferenced pointer s1 and the loop terminates. Note that the "increment portion" of this for statement has two increment expressions separated by a comma operator.

The first argument to both copy1 and copy2 must be an array large enough to hold the string in the second argument. Otherwise, an error may occur when an attempt is made to write into a memory location beyond the bounds of the array (recall that when using pointer-based arrays, there is no "built-in" bounds checking). Also, note that the second parameter of each function is declared as const char * (a pointer to a character constanti.e., a constant string). In both functions, the second argument is copied into the first argumentcharacters are copied from the second argument one at a time, but the characters are never modified. Therefore, the second parameter is declared to point to a constant value to enforce the principle of least privilegeneither function needs to modify the second argument, so neither function is allowed to modify the second argument.

Introduction to Computers, the Internet and World Wide Web

Introduction to C++ Programming

Introduction to Classes and Objects

Control Statements: Part 1

Control Statements: Part 2

Functions and an Introduction to Recursion

Arrays and Vectors

Pointers and Pointer-Based Strings

Classes: A Deeper Look, Part 1

Classes: A Deeper Look, Part 2

Operator Overloading; String and Array Objects

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

Templates

Stream Input/Output

Exception Handling

File Processing

Class string and String Stream Processing

Web Programming

Searching and Sorting

Data Structures

Bits, Characters, C-Strings and structs

Standard Template Library (STL)

Other Topics

Appendix A. Operator Precedence and Associativity Chart

Appendix B. ASCII Character Set

Appendix C. Fundamental Types

Appendix D. Number Systems

Appendix E. C Legacy Code Topics

Appendix F. Preprocessor

Appendix G. ATM Case Study Code

Appendix H. UML 2: Additional Diagram Types

Appendix I. C++ Internet and Web Resources

Appendix J. Introduction to XHTML

Appendix K. XHTML Special Characters

Appendix L. Using the Visual Studio .NET Debugger

Appendix M. Using the GNU C++ Debugger

Bibliography



C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net