Chapter 11: Pointers Christian Jacob 1 Pointer Basics 3 1.1 What Are Pointers? 3 1.2 Pointer Operators 4 1.3 Pointer Expressions 14 2 Pointers and Arrays 19 2.1 Pointer Arithmetic And Array Indexing 19 2.2 Pointers Versus Arrays An Example 20 2.3 Indexing of Pointers 24 2.4 Interchangeability of Pointers and Arrays 25 3 String Constants and Pointers 26 4 Arrays of Pointers 27 5 Problems with Pointers 28 5.1 Uninitialized Pointers 28 5.2 The Null Pointer Convention 29 5.3 Invalid Pointer Comparisons 30 5.4 Forgetting to Reset a Pointer 32 TOC 1 Back
Chapter 11: Pointers Christian Jacob 6 Multiple Indirection Pointers to Pointers 34 TOC 2 Back
Pointer Basics Chapter 11: Pointers Christian Jacob 1 Pointer Basics 1.1 What Are Pointers? A pointer is a variable that contains a memory address. Very often this address is the location of another variable. The general form of a pointer variable declaration in C++ is: type *variable-name; type variable-name * the pointer s base type. It must be a valid C++ type. the name of the pointer variable the at address operator Returns the value of the variable located at the address specified by its operand. int *int_pointer; // pointer to integer float *float_pointer; // pointer to float First Back TOC 3 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob 1.2 Pointer Operators There are two special operators that are used with pointers: & : address of operator A unary operator which returns the memory address of its operand. * : value at address operator A unary operator which returns the value of the variable located at the address specified by its operand. Example: int balance; int *balptr; balptr = &balance; 12 100 bal_ptr 100 - balance 130 - value First Back TOC 4 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example (continued): int balance, value; int *balptr; balance = 3200; // Step 1 balptr = &balance; // Step 2 value = *balptr; // Step 3 Step 1: Step 2: Step 3: 12 - bal_ptr 12 100 bal_ptr 12 100 bal_ptr 100 3200 balance 130 - value 100 3200 balance 130 - value 100 3200 balance 130 3200 value First Back TOC 5 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Importance of the Base Type How does C++ know how many bytes to copy into value from the address pointed to by balptr? How does the compiler know the proper number of bytes for any assignment using a pointer? Answer: The base type of the pointer determines the type of data that the compiler assumes the pointer is pointing to. The following code fragment is incorrect: int *int_ptr; double f; //... int_ptr = &f; // ERROR Technically correct, but not recommended (using a type cast operator): int_ptr = (int *) &f; First Back TOC 6 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example for why to be careful about type casts with pointers: #include <iostream.h> int main() { double x, y; int *ptr; x = 123.23; ptr = (int *) &x; // use cast to assign // double* to int* y = *ptr; cout << y; // What will this do? // What will this print? return(0); First Back TOC 7 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Assigning Values Through a Pointer Pointers can be used on the left side of assignment statements. The following code fragment assigns a value to the location pointed to by the pointer. int *ptr; *ptr = 101; At the location pointed to by p, assign the value 101. Increment and decrement operations work on pointers, too. (*ptr)++; At the location pointed to by p, increment the value by 1. First Back TOC 8 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example program for assigning values through pointers: #include <iostream.h> int main() { int *ptr, num; // 1 ptr = # // 2 *ptr = 100; // 3 cout << num << ; (*ptr)++; // 4 cout << num << ; (*ptr)*2; // 5 cout << num << \n ; Step 1 12 *_int ptr 50 _int num - return 0; First Back TOC 9 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example program for assigning values through pointers: #include <iostream.h> int main() { int *ptr, num; // 1 ptr = # // 2 *ptr = 100; // 3 cout << num << ; (*ptr)++; // 4 cout << num << ; (*ptr)*2; // 5 cout << num << \n ; Step 2 12 50 ptr 50 _int num - return 0; First Back TOC 10 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example program for assigning values through pointers: #include <iostream.h> int main() { int *ptr, num; // 1 ptr = # // 2 *ptr = 100; // 3 cout << num << ; (*ptr)++; // 4 cout << num << ; (*ptr)*2; // 5 cout << num << \n ; Step 3 12 50 ptr 50 100 num - return 0; First Back TOC 11 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example program for assigning values through pointers: #include <iostream.h> int main() { int *ptr, num; // 1 ptr = # // 2 *ptr = 100; // 3 cout << num << ; (*ptr)++; // 4 cout << num << ; (*ptr)*2; // 5 cout << num << \n ; Step 4 12 50 ptr 50 101 num - return 0; First Back TOC 12 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Example program for assigning values through pointers: #include <iostream.h> int main() { int *ptr, num; // 1 ptr = # // 2 *ptr = 100; // 3 cout << num << ; (*ptr)++; // 4 cout << num << ; (*ptr)*2; // 5 cout << num << \n ; Step 5 12 50 ptr 50 202 num - return 0; First Back TOC 13 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob 1.3 Pointer Expressions Pointers can be used in most C++ expressions. Keep in mind to use parentheses around pointer expressions. Pointer Arithmetic Only four arithmetic operators can be used on pointers: ++, --, +, and -. Example: (assuming 32-bit integers) int *p1; // assume: p1 == 2000 p1++; 1996 byte 1 byte 2 byte 3 byte 4 p1--; 2000 byte 1 byte 2 byte 3 byte 4 2004 byte 1 byte 2 byte 3 byte 4 First Back TOC 14 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Integers can be added or subtracted from pointers: You can subtract pointers of the same type from one another. You can not add pointers! However, you can add int numbers to pointers: #include <iostream.h> int main() { int i[10], *i_ptr; double f[10], *f_ptr; int x; i_ptr = i; // i_ptr points to first element of i f_ptr = f; // f_ptr points to first element of f for(x=0; x<10; x++) cout << i_ptr+x << << f_ptr+x << \n ; return 0; First Back TOC 15 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Output: The addresses of the array elements: 4 bytes int 8 bytes double 0xeffffd9c 0xeffffd48 0xeffffda0 0xeffffd50 0xeffffda4 0xeffffd58 0xeffffda8 0xeffffd60 0xeffffdac 0xeffffd68 0xeffffdb0 0xeffffd70 0xeffffdb4 0xeffffd78 0xeffffdb8 0xeffffd80 0xeffffdbc 0xeffffd88 0xeffffdc0 0xeffffd90 First Back TOC 16 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Pointer Comparisons Pointers may be compared using relational operators, such as!=, ==, <, and >. int main() { int num[10]; int *start, *end; start = num; end = &num[9]; while(start!= end) { cout << Enter a number: ; cin >> *start; start++; return 0; First Back TOC 17 Notes Prev Next Last
Pointer Basics Chapter 11: Pointers Christian Jacob Pointer Comparisons (2): using subtraction of pointers Pointers may be compared using relational operators, such as!=, ==, <, and >. int main() { int num[10]; int *start, *end; start = num; end = &num[9]; while((end - start) > 0) { cout << Enter a number: ; cin >> *start; start++; return 0; First Back TOC 18 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob 2 Pointers and Arrays 2.1 Pointer Arithmetic And Array Indexing In C++, using the name of an array without an index generates a pointer to the first element in the array: char str[80]; char *ptr; ptr = str; The last statement assigns the address of str[0] to ptr. Now there are two ways to access the n-th element in the array: str[n-1] or *(ptr + (n-1)) First Back TOC 19 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob 2.2 Pointers Versus Arrays An Example Here are two versions of a tokenizing program, a (usually) more efficient version with pointers, and a version using arrays. Tokeninzing Program: Pointer Version int main() { char str[80]; char token[80]; char *str_ptr, *tk_ptr; cout << Enter a sentence: ; gets(str); str_ptr = str;... First Back TOC 20 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob // Read a token at a time from the string while(*str_ptr) { tk_ptr = token; // start of token // Read characters until either a space or // the null terminator is encountered. while( *str_ptr!= && *str_ptr ) { *tk_ptr = *str_ptr; tk_ptr++; str_ptr++; if(*str_ptr) str_ptr++;// advance past space *tk_ptr = \0 ; // null terminate the token cout << token << endl; return 0; First Back TOC 21 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob Tokeninzing Program: Array Version #include <iostream> #include <cstdio> int main() { char str[80]; char token[80]; int i, j; cout << Enter a sentence: ; gets(str);... First Back TOC 22 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob // Read a token at a time from the string for(i=0; ; i++) { // Read characters until either a space or // a null terminator is encountered. for(j=0; str[i]!= && str[i]; j++, i++) token[j] = str[i]; token[j] = \0 ; // null termination cout << token << \n ; if(!str[i]) break; return 0; First Back TOC 23 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob 2.3 Indexing of Pointers One can not only use pointers to access array elements, but a pointer may also be indexed as if it were an array. #include <iostream> #include <cctype> int main() { char str[20] = hello tom ; char *p; int i; p = str; for(i=0; p[i]; i++) p[i] = toupper(p[i]); cout << p; return 0; First Back TOC 24 Notes Prev Next Last
Pointers and Arrays Chapter 11: Pointers Christian Jacob 2.4 Interchangeability of Pointers and Arrays Pointers and arrays are are strongly related in many cases. However, pointers and arrays are not completely interchangeable: int num[10]; int i; for(i=0; i<10; i++) { *num = i; num++; // ERROR -- cannot modify num num is a constant that points to the beginning of the array. Generally, an array name without an index generates a pointer to the beginning of an array, but it cannot be changed. *(num+3) = 100; // OK because num not modified First Back TOC 25 Notes Prev Next Last
String Constants and Pointers Chapter 11: Pointers Christian Jacob 3 String Constants and Pointers String constants appearing in program text are stored in the program s string table, which is generated at runtime. For every entry in the string table, a pointer to the string is generated. #include <iostream> int main() { char *s; s = Pointers are fun to use.\n ; cout << s; return 0; First Back TOC 26 Notes Prev Next Last
Arrays of Pointers Chapter 11: Pointers Christian Jacob 4 Arrays of Pointers Pointers can be arrayed like any other data type in C++. For example, to declare an array pi of 10 integer pointers, one would write: int *pi[10]; To assign the address of an integer variable called var to the third element of the pointer array, one would write: int var; pi[2] = &var; The following expression gives the value of var: *pi[2] First Back TOC 27 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob 5 Problems with Pointers 5.1 Uninitialized Pointers The classic example of a pointer error is the uninitialized pointer: // This program is wrong. int main() { int x, *p; x = 10; *p = x; // Where does p point? return 0; First Back TOC 28 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob 5.2 The Null Pointer Convention After a pointer is declared, but before it has been assigned, it will contain an arbitrary value. By convention, if a pointer contains the null (zero) value, it is assumed to point to nothing. float *p = 0; // p is now a null pointer Any type of pointer can be initialized to null when it is declared, thus avoiding accidental misuse of uninitialized pointers. To check for a null pointer, use an if statement: if(p) // succeeds if p is not null if(!p) // succeeds if p is null First Back TOC 29 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob 5.3 Invalid Pointer Comparisons Making any comparisons between pointers to two different objects, not belonging to the same array, may yield unexpected results. char s[80]; char y[80]; char *p1, *p2; p1 = s; p2 = y; if( p1 < p2)... This code makes invalid assumptions about C++ s strategy of placing variables in memory. First Back TOC 30 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob One should also never assume that two back-to-back arrays can be indexed as one: int first[10]; int second[10]; int *p, t; p = first; for(t=0; t<20; ++t) { *p = t; p++; First Back TOC 31 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob 5.4 Forgetting to Reset a Pointer The following program displays the ASCII codes of each character in a string entered from the keyboard. This program has a serious bug! int main() { char s[80], *p1; p1 = s; do{ cout << Enter a string: ; gets(p1); // read a string // print the ASCII values while(*p1) cout << (int) *p1++ << ; cout << \n ; while( strcmp(s, done ) ); return 0; First Back TOC 32 Notes Prev Next Last
Problems with Pointers Chapter 11: Pointers Christian Jacob Here is the corrected version, so that pointer p1 is reset to the beginning of the character array s at the beginning of each loop iteration: int main() { char s[80], *p1; do{ p1 = s; cout << Enter a string: ; gets(p1); // read a string // print the ASCII values while(*p1) cout << (int) *p1++ << ; cout << \n ; while( strcmp(s, done ) ); return 0; First Back TOC 33 Notes Prev Next Last
Multiple Indirection Pointers to Pointers Chapter 11: Pointers Christian Jacob 6 Multiple Indirection Pointers to Pointers A pointer to a pointer a chain of pointers is a form of multiple indirection. In the case of a normal pointer the value of the pointer is the address of a value. In the case of a pointer to a pointer the first pointer contains the address of the second, normal pointer. Single Indirection Pointer address Variable value Pointer Pointer Variable Multiple Indirection address address value First Back TOC 34 Notes Prev Next Last
Multiple Indirection Pointers to Pointers Chapter 11: Pointers Christian Jacob Example using multiple indirection: int main() { int x, *p, **q; x = 10; p = &x; q = &p; cout << **q; // prints the value of x return 0; First Back TOC 35 Notes Prev Next Last