1 5 1 Introduction Pointers Powerful but difficult
1 5. 1 Introduction • Pointers – Powerful, but difficult to master – Simulate pass by reference – Close relationship with arrays and strings
2 POINTERS & ADDRESSES C++ allows a programmer to access the address of variables. And addresses can be added, subtracted and compared. The address of a variable can be accessed with the & in front of the variable name, I. e. &temp : is the address of the var temp.
3 What the memory looks like MEMORY/RAM Address: 0 x 0001 Program int main () { int i, j, k; float l, m; i = 7; j = 8; …. . } Program byte code Variable storage space i 7 j 8 k Tells the computer to reserve enough room for an integer number Tag the first byte of storage with the name I 0 xffff
5. 2 4 Pointer Variable Declarations and Initialization • Pointer variables – Contain memory addresses as values – Normally, variable contains specific value (direct reference) – Pointers contain address of variable that has specific value count. Ptr (indirect reference) • Indirection 7 – Referencing value through pointer • Pointer declarations – * indicates variable is pointer int *my. Ptr; declares pointer to int, pointer of type int * – Multiple pointers require multiple asterisks int *my. Ptr 1, *my. Ptr 2; count 7
5. 2 Pointer Variable Declarations and Initialization • Can declare pointers to any data type • Pointer initialization – Initialized to 0, NULL, or address • 0 or NULL points to nothing 5
6 5. 3 Pointer Operators • & (address operator) – Returns memory address of its operand – Example int y = 5; int *y. Ptr; y. Ptr = &y; // y. Ptr gets address of y – y. Ptr “points to” y y. Ptr y 5 yptr 500000 600000 y 600000 address of y is value of yptr 5
7 5. 3 Pointer Operators • * (indirection/dereferencing operator) – Returns synonym for object its pointer operand points to – *y. Ptr returns y (because y. Ptr points to y). – dereferenced pointer is lvalue *yptr = 9; // assigns 9 to y • * and & are inverses of each other
1 2 3 // Fig. 5. 4: fig 05_04. cpp // Using the & and * operators. #include <iostream> 4 5 6 using std: : cout; using std: : endl; 7 8 9 10 11 int main() { int a; int *a. Ptr; 12 13 14 a = 7; a. Ptr = &a; 15 16 17 cout << "The address of a is " << &a << "n. The value of a. Ptr is " << a. Ptr; 18 19 20 cout << "nn. The value of a is " << a << "n. The value of *a. Ptr is " << *a. Ptr; 21 22 23 24 cout << "nn. Showing that * and & are inverses of " << "each other. n&*a. Ptr = " << &*a. Ptr << "n*&a. Ptr = " << *&a. Ptr << endl; 25 8 // a is an integer // a. Ptr is a pointer to an integer // a. Ptr assigned address of a fig 05_04. cpp (1 of 2) * and & are inverses of each other
26 27 28 return 0; 9 // indicates successful termination } // end main The address of a is 0012 FED 4 The value of a. Ptr is 0012 FED 4 The value of a is 7 The value of *a. Ptr is 7 Showing that * and & are inverses of each other. &*a. Ptr = 0012 FED 4 *&a. Ptr = 0012 FED 4 * and & are inverses; same result when both applied to a. Ptr fig 05_04. cpp (2 of 2) fig 05_04. cpp output (1 of 1)
10 Pointer declaration You must declare a pointer to point to a specific data type. This way the computer knows how many bytes to retrieve Char ptr Int ptr address One byte is retrieved Two bytes Four bytes Float ptr address
11 5. 4 Calling Functions by Reference • 3 ways to pass arguments to function – Pass by value – Pass by reference with reference arguments – Pass by reference with pointer arguments • return can return one value from function • Arguments passed to function using reference arguments – Modify original values of arguments – More than one value “returned”
12 5. 4 Calling Functions by Reference • Pass by reference with pointer arguments – Simulate pass by reference • Use pointers and indirection operator – Pass address of argument using & operator – Arrays not passed with & because array name already pointer – * operator used as alias/nickname for variable inside of function
1 2 3 // Fig. 5. 6: fig 05_06. cpp // Cube a variable using pass-by-value. #include <iostream> 4 5 6 using std: : cout; using std: : endl; 7 8 int cube. By. Value( int ); 9 10 11 12 int main() { int number = 5; 13 // prototype fig 05_06. cpp Pass number by value; result << number; (1 of 2) returned by cube. By. Value 13 14 cout << "The original value of number is " 15 16 17 // pass number by value to cube. By. Value number = cube. By. Value( number ); 18 19 cout << "n. The new value of number is " << number << endl; 20 21 return 0; 22 23 24 } // end main // indicates successful termination
25 26 27 28 29 30 14 // calculate and return cube of integer argument int cube. By. Value( int n ) { cube. By. Value receives return n * n; // cube local variable n and return result parameter passed by value } // end function cube. By. Value The original value of number is 5 The new value of number is 125 Cubes and returns local variable n fig 05_06. cpp (2 of 2) fig 05_06. cpp output (1 of 1)
1 2 3 4 // Fig. 5. 7: fig 05_07. cpp // Cube a variable using pass-by-reference // with a pointer argument. #include <iostream> 5 6 7 using std: : cout; using std: : endl; 8 9 void cube. By. Reference( int * ); 10 11 12 13 int main() { int number = 5; 15 Prototype indicates parameter is pointer to int // prototype 14 15 cout << "The original value of number is " << number; 16 17 18 // pass address of number to cube. By. Reference( &number ); 19 20 cout << "n. The new value of number is " << number << endl; 21 22 return 0; 23 24 25 } // end main Apply address operator & to pass address of number to cube. By. Reference // indicates successful termination fig 05_07. cpp (1 of 2) cube. By. Reference modified variable number
26 27 28 29 30 31 16 // calculate cube of *n. Ptr; modifies variable number in main void cube. By. Reference( int *n. Ptr ) { *n. Ptr = *n. Ptr * *n. Ptr; // cube *n. Ptr } // end function cube. By. Reference The original value of number is 5 The new value of number is 125 cube. By. Reference receives address of int variable, i. e. , pointer to an int Modify and access int variable using indirection operator * fig 05_07. cpp (2 of 2) fig 05_07. cpp output (1 of 1)
17 5. 5 Using const with Pointers • const qualifier – Value of variable should not be modified – const used when function does not need to change a variable • Principle of least privilege – Award function enough access to accomplish task, but no more • Four ways to pass pointer to function – Nonconstant pointer to nonconstant data • Highest amount of access – Nonconstant pointer to constant data – Constant pointer to nonconstant data – Constant pointer to constant data • Least amount of access
1 2 3 4 // Fig. 5. 10: fig 05_10. cpp // Converting lowercase letters to uppercase letters // using a non-constant pointer to non-constant data. #include <iostream> 5 6 7 using std: : cout; using std: : endl; 8 9 #include <cctype> 10 11 void convert. To. Uppercase( char * ); 12 13 14 15 int main() { char phrase[] = "characters and $32. 98"; // prototypes for Parameter is nonconstant pointer to nonconstant data islower and toupper fig 05_10. cpp (1 of 2) convert. To. Uppercase modifies variable phrase 16 17 18 19 20 cout << "The phrase before conversion is: " << phrase; convert. To. Uppercase( phrase ); cout << "n. The phrase after conversion is: " << phrase << endl; 21 22 return 0; 23 24 25 } // end main // indicates successful termination 18
26 27 28 29 30 31 32 33 34 35 36 37 38 The 19 // convert string to uppercase letters void convert. To. Uppercase( char *s. Ptr ) { while ( *s. Ptr != '