Pointers CS102- Programming Fundamentals
Pointers and the Address Operator •Each variable in program is stored at a unique address •Use address operator & to get address of a variable: int num = -23; cout << &num; // prints address // in hexadecimal •The address of a memory location is a pointer 2/8/2017
Pointer Data Type and Pointer Variables • Pointer variable: • variable that holds an address • content is a memory address •Pointers provide an alternate way to access memory locations • There is no name associated with the pointer data type in C++ 2/8/2017
Declaring Pointer Variables • Syntax: • Examples: int *p; char *ch; • These statements are equivalent: int *p; int* p; int * p; 2/8/2017
Declaring Pointer Variables (cont'd.) • In the statement: int* p, q; only p is the pointer variable, not q; here q is an int variable • To avoid confusion, attach the character * to the variable name: int *p, q; int *p, *q; 2/8/2017
Pointer Variables •Definition: int *intptr; •Read as: “intptr can hold the address of an int” •Spacing in definition does not matter: int * intptr; int* intptr; 2/8/2017
Address of Operator (&) • The ampersand, &, is called the address of operator • The address of operator is a unary operator that returns the address of its operand 2/8/2017
Dereferencing Operator (*) • When used as a unary operator, * is the dereferencing operator or indirection operator • Refers to object to which its operand points • Example: • To print the value of x, using p: • To store a value in x, using p: 2/8/2017
Dereferencing Operator (*) (cont’d.) 2/8/2017
Pointer Variables •Assignment: int num = 25; int *intptr; intptr = &num; •Memory layout: •Can access num using intptr and indirection operator *: cout << intptr; // prints 0x4a00 cout << *intptr; // prints 25 num intptr 25 0x4a00 address of num: 0x4a00 2/8/2017
More examples 2/8/2017
Pointers and Arrays 2/8/2017
The Relationship Between Arrays and Pointers •Array name is starting address of array int vals[] = {4, 7, 11}; cout << vals; // displays 0x4a00 cout << vals[0]; // displays 4 4 7 11 Base Address: starting address of vals: 0x4a00 2/8/2017
Conti… (Output = ?) int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; cout << "n Number : " << number; cout << "n&Number : " << &number; cout << "n&number[0] : " << &number[0] << endl; //Output: Number : 1245020 &Number : 1245020 &number[0] : 1245020 2/8/2017
The Relationship Between Arrays and Pointers •Array name can be used as a pointer constant int vals[] = {4, 7, 11}; cout << *vals; // displays 4 •Pointer can be used as an array name int *valptr = vals; cout << valptr[1]; // displays 7 2/8/2017
Pointers in Expressions •Given: int vals[]={4,7,11}; int *valptr = vals; •What is valptr + 1? • It means (address in valptr) + (1 * size of an int) cout << *(valptr+1); // displays 7 cout << *(valptr+2); // displays 11 •Must use ( ) in expression 2/8/2017
Array Access • Array elements can be accessed in many ways Array access method Example array name and [ ] vals[2] = 17; pointer to array and [ ] valptr[2] = 17; array name and subscript arithmetic *(vals+2) = 17; pointer to array and subscript arithmetic *(valptr+2) = 17; 2/8/2017
Array Access •Array notation • vals[i] • is equivalent to the pointer notation • *(vals + i) •No bounds checking performed on array access 2/8/2017
Conti… int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Values"; cout << "n number[0] : " << number[0]; cout << "n*pNumber : " << *pNumbers; ---------------------------------------------------------------------------Output Values number[0] : 31 *pNumber : 31 2/8/2017
Example Conti… int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "n Number : " << Number; cout << "npNumbers : " << pNumbers; cout << "nnValues"; cout << "n Number [0] : " << number[0]; cout << "npNumbers[0] : " << pNumbers[0]; cout << "n Number [1] : " << number[1]; cout << "npNumbers[1] : " << pNumbers[1]; Addresses Number : 1245020 pNumbers : 1245020 Values Number [0] : 31 pNumbers[0] : 31 Number [1] : 28 pNumbers[1] : 28 2/8/2017
Examples… (Output : ?) #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; for (int i = 0; i < MAX; i++) { cout << "Value of var[" << i << "] = "; cout << var[i] << endl; } return 0; } //Output: Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200 2/8/2017
Examples … (Output with pointer : ?) #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; int *ptr[MAX]; for (int i = 0; i < MAX; i++) { ptr[i] = &var[i]; // assign the address of integer. } for (int i = 0; i < MAX; i++) { cout << "Value of var[" << i << "] = "; cout << *ptr[i] << endl; } return 0; } //Output: Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200 2/8/2017
Examples Conti… int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "n Number : " << Number; cout << "npNumbers : " << pNumbers; cout << "n Number +1 : " << Number+1; cout << "npNumbers+1 : " << pNumbers+1; cout << "n Number +2 : " << Number+2; cout << "npNumbers+2 : " << pNumbers+2; Addresses Number : 1245020 pNumbers : 1245020 Number +1 : 1245024 pNumbers+1: 1245024 Number +2 : 1245028 pNumbers+2 : 1245028 2/8/2017
Pointers and Functions 2/8/2017
Pointers as Function Parameters • A pointer can be a parameter • Works like a reference parameter to allow change to argument from within function • A pointer parameter must be explicitly dereferenced to access the contents at that address • When to pass parameters by value, reference, and pointer @ http://www.cplusplus.com/articles/z6vU7k9E/ 2/8/2017
Pointers as Function Parameters • Requires: 1) asterisk * on parameter in prototype and heading void getNum(int *ptr); 2) asterisk * in body to dereference the pointer cin >> *ptr; 3) address as argument to the function getNum(&num); 2/8/2017
Pointers as Function Parameters void swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; } int num1 = 2, num2 = -3; swap(&num1, &num2); 2/8/2017
Functions and Pointers • A pointer variable can be passed as a parameter either by value or by reference • To make a pointer a reference parameter in a function heading, use &: void pointerParameters(int* &p, double *q) { . . . } 2/8/2017
Pointers and Function Return Values • A function can return a value of type pointer: int* testExp(...) { . . . } 2/8/2017
Pointers to Constants and Constant Pointers •Pointer to a constant: cannot change the value that is pointed at •Constant pointer: address in pointer cannot change once pointer is initialized 2/8/2017
Pointers to Constant •Must use const keyword in pointer definition: const double taxRates[] = {0.65, 0.8, 0.75}; const double *ratePtr; •Use const keyword for pointers in function headers to protect data from modification from within function 2/8/2017
Constant Pointers •Defined with const keyword adjacent to variable name: int classSize = 24; int * const classPtr = &classSize; •Must be initialized when defined •Can be used without initialization as a function parameter • Initialized by argument when function is called • Function can receive different arguments on different calls •While the address in the pointer cannot change, the data at that address may be changed 2/8/2017
Pointer’s Arithmetic 2/8/2017
Pointer Arithmetic • Some arithmetic operators can be used with pointers: • Increment and decrement operators ++, -- • Integers can be added to or subtracted from pointers using the operators +, -, +=, and -= • One pointer can be subtracted from another by using the subtraction operator - 2/8/2017
Pointer Arithmetic Assume the variable definitions int vals[]={4,7,11}; int *valptr = vals; Examples of use of ++ and -- valptr++; // points at 7 valptr--; // now points at 4 2/8/2017
Pointer Arithmetic Assume the variable definitions: int vals[]={4,7,11}; int *valptr = vals; Example of use of + to add an int to a pointer: cout << *(valptr + 2) This statement will print 11 2/8/2017
Assume the variable definitions: int vals[]={4,7,11}; int *valptr = vals; Example of use of +=: valptr = vals; // points at 4 valptr += 2; // points at 11 Pointer Arithmetic 2/8/2017
Assume the variable definitions int vals[] = {4,7,11}; int *valptr = vals; Example of pointer subtraction valptr += 2; cout << valptr - val; This statement prints 2: the number of ints between valptr and val Pointer Arithmetic 2/8/2017
Pointer Arithmetic 2/8/2017
Initializing Pointer Variables • C++ does not automatically initialize variables • Pointer variables must be initialized if you do not want them to point to anything • Initialized using the constant value 0 • Called the null pointer • Example: p = 0; • Or, use the NULL named constant: • p = NULL; • The number 0 is the only number that can be directly assigned to a pointer variable 2/8/2017
Initializing Pointers Conti… •Can initialize to NULL or 0 (zero) • int *ptr = NULL; •Can initialize to addresses of other variables int num, *numPtr = &num; int val[ISIZE], *valptr = val; •Initial value must have correct type float cost; int *ptr = &cost; // won't work 2/8/2017
Comparing Pointers •Relational operators can be used to compare addresses in pointers •Comparing addresses in pointers is not the same as comparing contents pointed at by pointers: if (ptr1 == ptr2) // compares // addresses if (*ptr1 == *ptr2) // compares // contents 2/8/2017
Operations on Pointer Variables • Assignment: value of one pointer variable can be assigned to another pointer of same type • Relational operations: two pointer variables of same type can be compared for equality, etc. • Some limited arithmetic operations: • Integer values can be added and subtracted from a pointer variable • Value of one pointer variable can be subtracted from another pointer variable 2/8/2017
Operations on Pointer Variables (cont'd.) • Examples: int *p, *q; p = q; • In this case, p == q will evaluate to true, and p != q will evaluate to false int *p double *q; • In this case, q++; increments value of q by 8, and p = p + 2; increments value of p by 8 2/8/2017
Operations on Pointer Variables (cont'd.) • Pointer arithmetic can be very dangerous • The program can accidentally access the memory locations of other variables and change their content without warning • Some systems might terminate the program with an appropriate error message • Always exercise extra care when doing pointer arithmetic 2/8/2017
Dynamic Memory Allocation NEW & DELETE Operators 2/8/2017
Stack & Heap Memory Stack • the stack grows and shrinks as functions push and pop local variables • there is no need to manage the memory yourself, variables are allocated and freed automatically • the stack has size limits • stack variables only exist while the function that created them, is running • The Heap 2/8/2017
Stack & Heap Memory Stack • very fast access • don't have to explicitly de- allocate variables • space is managed efficiently by CPU, memory will not become fragmented • local variables only • limit on stack size (OS- dependent) • variables cannot be resized Heap • variables can be accessed globally • no limit on memory size • (relatively) slower access • no guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed • you must manage memory (you're in charge of allocating and freeing variables) • variables can be resized using realloc() 2/8/2017
Dynamic Variables • Dynamic variables: created during execution • C++ creates dynamic variables using pointers • Two operators, new and delete, to create and destroy dynamic variables • new and delete are reserved words 2/8/2017
Operator new • new has two forms: • where intExp is any expression evaluating to a positive integer • new allocates memory (a variable) of the designated type and returns a pointer to it • The address of the allocated memory • The allocated memory is uninitialized 2/8/2017
Operator new (cont'd.) • The statement: p = &x; • Stores address of x in p • However, no new memory is allocated • The statement: p = new int; • Creates a variable during program execution somewhere in memory, and stores the address of the allocated memory in p • To access allocated memory: *p 2/8/2017
Operator new (cont'd.) 2/8/2017
Operator new (cont'd.) • new allocates memory space of a specific type and returns the (starting) address of the allocated memory space • If new is unable to allocate the required memory space, then it throws bad_alloc exception • If this exception is not handled, it terminates the program with an error message 2/8/2017
Operator delete 2/8/2017
Operator delete (cont'd.) • To avoid memory leak, when a dynamic variable is no longer needed, destroy it • Deallocate its memory • delete is used to destroy dynamic variables • Syntax: • Tip: to avoid dangling pointers, set variable to NULL afterwards 2/8/2017
Dynamic Arrays • Dynamic array: array created during the execution of a program • Example: int *p; p = new int[10]; *p = 25; p++; //to point to next array component *p = 35; stores 25 into the first memory location stores 35 into the second memory location 2/8/2017
Dynamic Arrays (cont'd.) • C++ allows us to use array notation to access these memory locations • The statements: p[0] = 25; p[1] = 35; store 25 and 35 into the first and second array components, respectively 2/8/2017
Dynamic Arrays (cont'd.) 2/8/2017
Dynamic Arrays (cont'd.) 2/8/2017
Dynamic Arrays (cont'd.) • The value of list (1000) is constant • Cannot be altered during program execution • The increment and decrement operations cannot be applied to list • If p is a pointer variable of type int, then: p = list; copies the value of list, the base address of the array, into p • We can perform ++ and -- operations on p • An array name is a constant pointer 2/8/2017
Dynamic Arrays (cont'd.) 2/8/2017
Dynamic Two-Dimensional Arrays • You can create dynamic multidimensional arrays • Examples: declares board to be an array of four pointers wherein each pointer is of type int creates the rows of board declares board to be a pointer to a pointer 2/8/2017
Pointer to Pointer (Multiple Indirection) • Define a pointer to a pointer • First pointer contains the address of the second pointer • Declared with ** like int **var; • Also called “Double Pointer” e.g. int **ipp; int i = 5, j = 6; k = 7; int *ip1 = &i, *ip2 = &j; ipp = &ip1; 2/8/2017
Double Pointer #include <iostream> using namespace std; int main () { int var; int *ptr; int **pptr; var = 3000; // take the address of var ptr = &var; // take the address of ptr using address of operator & pptr = &ptr; // take the value using pptr cout << "Value of var :" << var << endl; cout << "Value available at *ptr :" << *ptr << endl; cout << "Value available at **pptr :" << **pptr << endl; return 0; } 2/8/2017
Double Pointer & Dynamic 2D Array You may create fully dynamic two dimensional array using 2d pointer. ------------------------------------- //Create your pointer int **ptr; //Assign first dimension ptr = new int*[5]; //Assign second dimension for(int i = 0; i < 5; i++) ptr[i] = new int[5]; 2/8/2017
Conti… 2/8/2017
Shallow vs. Deep Copy & Pointers 2/8/2017
Shallow versus Deep Copy and Pointers • Assume some data is stored in the array: • If we execute: 2/8/2017
Shallow versus Deep Copy and Pointers (cont'd.) • Shallow copy: two or more pointers of the same type point to the same memory • They point to the same data 2/8/2017
Shallow versus Deep Copy and Pointers (cont'd.) • Deep copy: two or more pointers have their own data 2/8/2017
Void Pointer • Exception: pointer to void (type void *) • Generic pointer, represents any type • No casting needed to convert a pointer to void pointer • void pointers cannot be dereferenced int nValue; float fValue; double sValue; void *pVoid; pVoid = &nValue; // valid pVoid = &fValue; // valid pVoid = &sValue; // valid int nValue = 5; void *pVoid = &nValue; // can not dereference pVoid because it is a void pointer int *pInt = static_cast<int*>(pVoid); // cast from void* to int* cout << *pInt << endl; // can dereference pInt 2/8/2017
sizeof() of operator • sizeof • Unary operator returns size of operand in bytes • For arrays, sizeof returns ( size of 1 element ) * ( number of elements ) • If sizeof( int ) = 4, then int myArray[10]; cout << sizeof(myArray); will print 40 • sizeof can be used with • Variable names • Type names • Constant values 2/8/2017
References • http://www.functionx.com/cpp/Lesson14.htm 2/8/2017
Home Activity Pointers 2/8/2017
Home Tasks … ! ! ! • Count how many numbers are stored in a file. Then create an array to store those numbers and sort. • Implement a sorting algorithm and use swap(int *, int *) to swap the values of array elements. • Use sizeof(…) to find the size of simple variables and array. Example is give in examples section • Create a text file which has different number of elements in each row. Then create an compatible 2D array to read and store the values. Perform different operations. 2/8/2017
Example – I 1 // Fig. 5.10: fig05_10.cpp 2 // Converting lowercase letters to uppercase letters 3 // using a non-constant pointer to non-constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <cctype> // prototypes for islower and toupper 10 11 void convertToUppercase( char * ); 12 13 int main() 14 { 15 char phrase[] = "characters and $32.98"; 16 17 cout << "The phrase before conversion is: " << phrase; 18 convertToUppercase( phrase ); 19 cout << "nThe phrase after conversion is: " 20 << phrase << endl; 21 22 return 0; // indicates successful termination 23 24 } // end main 25 2/8/2017
Example – I… 26 // convert string to uppercase letters 27 void convertToUppercase( char *sPtr ) 28 { 29 while ( *sPtr != '0' ) { // current character is not '0' 30 31 if ( islower( *sPtr ) ) // if character is lowercase, 32 *sPtr = toupper( *sPtr ); // convert to uppercase 33 34 ++sPtr; // move sPtr to next character in string 35 36 } // end while 37 38 } // end function convertToUppercase The phrase before conversion is: characters and $32.98 The phrase after conversion is: CHARACTERS AND $32.98 Parameter sPtr nonconstant pointer to nonconstant data Function islower returns true if character is lowercase Function toupper returns corresponding uppercase character if original character lowercase; otherwise toupper returns original (uppercase) character When operator ++ applied to pointer that points to array, memory address stored in pointer modified to point to next element of array. 2/8/2017
Example – II 1 // Fig. 5.11: fig05_11.cpp 2 // Printing a string one character at a time using 3 // a non-constant pointer to constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 void printCharacters( const char * ); 10 11 int main() 12 { 13 char phrase[] = "print characters of a string"; 14 15 cout << "The string is:n"; 16 printCharacters( phrase ); 17 cout << endl; 18 19 return 0; // indicates successful termination 20 21 } // end main 22 2/8/2017
Example – II… 23 // sPtr cannot modify the character to which it points, 24 // i.e., sPtr is a "read-only" pointer 25 void printCharacters( const char *sPtr ) 26 { 27 for ( ; *sPtr != '0'; sPtr++ ) // no initialization 28 cout << *sPtr; 29 30 } // end function printCharacters The string is: print characters of a string sPtr is nonconstant pointer to constant data; cannot modify character to which sPtr points. 2/8/2017
Example – III 1 // Fig. 5.11: fig05_11.cpp 2 // Printing a string one character at a time using 3 // a non-constant pointer to constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 void printCharacters( const char * ); 10 11 int main() 12 { 13 char phrase[] = "print characters of a string"; 14 15 cout << "The string is:n"; 16 printCharacters( phrase ); 17 cout << endl; 18 19 return 0; // indicates successful termination 20 21 } // end main 22 2/8/2017
Example – IV 1 // Fig. 5.12: fig05_12.cpp 2 // Attempting to modify data through a 3 // non-constant pointer to constant data. 4 5 void f( const int * ); // prototype 6 7 int main() 8 { 9 int y; 10 11 f( &y ); // f attempts illegal modification 12 13 return 0; // indicates successful termination 14 15 } // end main 16 17 // xPtr cannot modify the value of the variable 18 // to which it points 19 void f( const int *xPtr ) 20 { 21 *xPtr = 100; // error: cannot modify a const object 22 23 } // end function f d:cpphtp4_examplesch05Fig05_12.cpp(21) : error C2166: l-value specifies const object Parameter is nonconstant pointer to constant data. Pass address of int variable y to attempt illegal modification. Attempt to modify const object pointed to by xPtr. Error produced when attempting to compile. 2/8/2017
Example – V 1 // Fig. 5.13: fig05_13.cpp 2 // Attempting to modify a constant pointer to 3 // non-constant data. 4 5 int main() 6 { 7 int x, y; 8 9 // ptr is a constant pointer to an integer that can 10 // be modified through ptr, but ptr always points to the 11 // same memory location. 12 int * const ptr = &x; 13 14 *ptr = 7; // allowed: *ptr is not const 15 ptr = &y; // error: ptr is const; cannot assign new address 16 17 return 0; // indicates successful termination 18 19 } // end main d:cpphtp4_examplesch05Fig05_13.cpp(15) : error C2166: l-value specifies const object ptr is constant pointer to integer. Can modify x (pointed to by ptr) since x not constant. Cannot modify ptr to point to new address since ptr is constant. Line 15 generates compiler error by attempting to assign new address to constant pointer. 2/8/2017
1 // Fig. 5.14: fig05_14.cpp 2 // Attempting to modify a constant pointer to constant data. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 int x = 5, y; 11 12 // ptr is a constant pointer to a constant integer. 13 // ptr always points to the same location; the integer 14 // at that location cannot be modified. 15 const int *const ptr = &x; 16 17 cout << *ptr << endl; 18 19 *ptr = 7; // error: *ptr is const; cannot assign new value 20 ptr = &y; // error: ptr is const; cannot assign new address 21 22 return 0; // indicates successful termination 23 24 } // end main ptr is constant pointer to integer constant. Cannot modify x (pointed to by ptr) since *ptr declared constant. Cannot modify ptr to point to new address since ptr is constant. d:cpphtp4_examplesch05Fig05_14.cpp(19) : error C2166: l-value specifies const object d:cpphtp4_examplesch05Fig05_14.cpp(20) : error C2166: l-value specifies const object Line 19 generates compiler error by attempting to modify constant object. Line 20 generates compiler error by attempting to assign new address to constant pointer. Example–VI 2/8/2017
Example –VII 1 // Fig. 5.16: fig05_16.cpp 2 // Sizeof operator when used on an array name 3 // returns the number of bytes in the array. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 size_t getSize( double * ); // prototype 10 11 int main() 12 { 13 double array[ 20 ]; 14 15 cout << "The number of bytes in the array is " 16 << sizeof( array ); 17 18 cout << "nThe number of bytes returned by getSize is " 19 << getSize( array ) << endl; 20 21 return 0; // indicates successful termination 22 23 } // end main 24 Operator sizeof applied to an array returns total number of bytes in array. Function getSize returns number of bytes used to store array address. 2/8/2017
Example – VIII 20 cout << "sizeof c = " << sizeof c 21 << "tsizeof(char) = " << sizeof( char ) 22 << "nsizeof s = " << sizeof s 23 << "tsizeof(short) = " << sizeof( short ) 24 << "nsizeof i = " << sizeof i 25 << "tsizeof(int) = " << sizeof( int ) 26 << "nsizeof l = " << sizeof l 27 << "tsizeof(long) = " << sizeof( long ) 28 << "nsizeof f = " << sizeof f 29 << "tsizeof(float) = " << sizeof( float ) 30 << "nsizeof d = " << sizeof d 31 << "tsizeof(double) = " << sizeof( double ) 32 << "nsizeof ld = " << sizeof ld 33 << "tsizeof(long double) = " << sizeof( long double ) 34 << "nsizeof array = " << sizeof array 35 << "nsizeof ptr = " << sizeof ptr 36 << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main Operator sizeof can be used on variable name. Operator sizeof can be used on type name. sizeof c = 1 sizeof(char) = 1 sizeof s = 2 sizeof(short) = 2 sizeof i = 4 sizeof(int) = 4 sizeof l = 4 sizeof(long) = 4 sizeof f = 4 sizeof(float) = 4 sizeof d = 8 sizeof(double) = 8 sizeof ld = 8 sizeof(long double) = 8 sizeof array = 80 sizeof ptr = 42/8/2017
Example – IX 1 // Fig. 5.25: fig05_25.cpp 2 // Multipurpose sorting program using function pointers. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 // prototypes 14 void bubble( int [], const int, bool (*)( int, int ) ); 15 void swap( int * const, int * const ); 16 bool ascending( int, int ); 17 bool descending( int, int ); 18 19 int main() 20 { 21 const int arraySize = 10; 22 int order; 23 int counter; 24 int a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 25 Parameter is pointer to function that receives two integer parameters and returns bool result. 2/8/2017
Example – IX… 26 cout << "Enter 1 to sort in ascending order,n" 27 << "Enter 2 to sort in descending order: "; 28 cin >> order; 29 cout << "nData items in original ordern"; 30 31 // output original array 32 for ( counter = 0; counter < arraySize; counter++ ) 33 cout << setw( 4 ) << a[ counter ]; 34 35 // sort array in ascending order; pass function ascending 36 // as an argument to specify ascending sorting order 37 if ( order == 1 ) { 38 bubble( a, arraySize, ascending ); 39 cout << "nData items in ascending ordern"; 40 } 41 42 // sort array in descending order; pass function descending 43 // as an agrument to specify descending sorting order 44 else { 45 bubble( a, arraySize, descending ); 46 cout << "nData items in descending ordern"; 47 } 48 2/8/2017
Example – IX… 49 // output sorted array 50 for ( counter = 0; counter < arraySize; counter++ ) 51 cout << setw( 4 ) << a[ counter ]; 52 53 cout << endl; 54 55 return 0; // indicates successful termination 56 57 } // end main 58 59 // multipurpose bubble sort; parameter compare is a pointer to 60 // the comparison function that determines sorting order 61 void bubble( int work[], const int size, 62 bool (*compare)( int, int ) ) 63 { 64 // loop to control passes 65 for ( int pass = 1; pass < size; pass++ ) 66 67 // loop to control number of comparisons per pass 68 for ( int count = 0; count < size - 1; count++ ) 69 70 // if adjacent elements are out of order, swap them 71 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) 72 swap( &work[ count ], &work[ count + 1 ] ); compare is pointer to function that receives two integer parameters and returns bool result. Parentheses necessary to indicate pointer to function Call passed function compare; dereference pointer to execute function. 2/8/2017
Example – IX… 73 74 } // end function bubble 75 76 // swap values at memory locations to which 77 // element1Ptr and element2Ptr point 78 void swap( int * const element1Ptr, int * const element2Ptr ) 79 { 80 int hold = *element1Ptr; 81 *element1Ptr = *element2Ptr; 82 *element2Ptr = hold; 83 84 } // end function swap 85 86 // determine whether elements are out of order 87 // for an ascending order sort 88 bool ascending( int a, int b ) 89 { 90 return b < a; // swap if b is less than a 91 92 } // end function ascending 93 2/8/2017
Example – IX… 94 // determine whether elements are out of order 95 // for a descending order sort 96 bool descending( int a, int b ) 97 { 98 return b > a; // swap if b is greater than a 99 100 } // end function descending Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 2 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in descending order 89 68 45 37 12 10 8 6 4 2 2/8/2017
Example – X 1 // Fig. 5.26: fig05_26.cpp 2 // Demonstrating an array of pointers to functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 // function prototypes 10 void function1( int ); 11 void function2( int ); 12 void function3( int ); 13 14 int main() 15 { 16 // initialize array of 3 pointers to functions that each 17 // take an int argument and return void 18 void (*f[ 3 ])( int ) = { function1, function2, function3 }; 19 20 int choice; 21 22 cout << "Enter a number between 0 and 2, 3 to end: "; 23 cin >> choice; 24 Array initialized with names of three functions; function names are pointers. 2/8/2017
Example – X… 25 // process user's choice 26 while ( choice >= 0 && choice < 3 ) { 27 28 // invoke function at location choice in array f 29 // and pass choice as an argument 30 (*f[ choice ])( choice ); 31 32 cout << "Enter a number between 0 and 2, 3 to end: "; 33 cin >> choice; 34 } 35 36 cout << "Program execution completed." << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was callednn"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array. 2/8/2017
Example – X… 49 void function2( int b ) 50 { 51 cout << "You entered " << b 52 << " so function2 was callednn"; 53 54 } // end function2 55 56 void function3( int c ) 57 { 58 cout << "You entered " << c 59 << " so function3 was callednn"; 60 61 } // end function3 Enter a number between 0 and 2, 3 to end: 0 You entered 0 so function1 was called Enter a number between 0 and 2, 3 to end: 1 You entered 1 so function2 was called Enter a number between 0 and 2, 3 to end: 2 You entered 2 so function3 was called Enter a number between 0 and 2, 3 to end: 3 Program execution completed. 2/8/2017

Pf cs102 programming-9 [pointers]

  • 1.
  • 2.
    Pointers and theAddress Operator •Each variable in program is stored at a unique address •Use address operator & to get address of a variable: int num = -23; cout << &num; // prints address // in hexadecimal •The address of a memory location is a pointer 2/8/2017
  • 3.
    Pointer Data Typeand Pointer Variables • Pointer variable: • variable that holds an address • content is a memory address •Pointers provide an alternate way to access memory locations • There is no name associated with the pointer data type in C++ 2/8/2017
  • 4.
    Declaring Pointer Variables •Syntax: • Examples: int *p; char *ch; • These statements are equivalent: int *p; int* p; int * p; 2/8/2017
  • 5.
    Declaring Pointer Variables(cont'd.) • In the statement: int* p, q; only p is the pointer variable, not q; here q is an int variable • To avoid confusion, attach the character * to the variable name: int *p, q; int *p, *q; 2/8/2017
  • 6.
    Pointer Variables •Definition: int *intptr; •Readas: “intptr can hold the address of an int” •Spacing in definition does not matter: int * intptr; int* intptr; 2/8/2017
  • 7.
    Address of Operator(&) • The ampersand, &, is called the address of operator • The address of operator is a unary operator that returns the address of its operand 2/8/2017
  • 8.
    Dereferencing Operator (*) •When used as a unary operator, * is the dereferencing operator or indirection operator • Refers to object to which its operand points • Example: • To print the value of x, using p: • To store a value in x, using p: 2/8/2017
  • 9.
    Dereferencing Operator (*)(cont’d.) 2/8/2017
  • 10.
    Pointer Variables •Assignment: int num= 25; int *intptr; intptr = &num; •Memory layout: •Can access num using intptr and indirection operator *: cout << intptr; // prints 0x4a00 cout << *intptr; // prints 25 num intptr 25 0x4a00 address of num: 0x4a00 2/8/2017
  • 11.
  • 12.
  • 13.
    The Relationship BetweenArrays and Pointers •Array name is starting address of array int vals[] = {4, 7, 11}; cout << vals; // displays 0x4a00 cout << vals[0]; // displays 4 4 7 11 Base Address: starting address of vals: 0x4a00 2/8/2017
  • 14.
    Conti… (Output =?) int number[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; cout << "n Number : " << number; cout << "n&Number : " << &number; cout << "n&number[0] : " << &number[0] << endl; //Output: Number : 1245020 &Number : 1245020 &number[0] : 1245020 2/8/2017
  • 15.
    The Relationship BetweenArrays and Pointers •Array name can be used as a pointer constant int vals[] = {4, 7, 11}; cout << *vals; // displays 4 •Pointer can be used as an array name int *valptr = vals; cout << valptr[1]; // displays 7 2/8/2017
  • 16.
    Pointers in Expressions •Given: intvals[]={4,7,11}; int *valptr = vals; •What is valptr + 1? • It means (address in valptr) + (1 * size of an int) cout << *(valptr+1); // displays 7 cout << *(valptr+2); // displays 11 •Must use ( ) in expression 2/8/2017
  • 17.
    Array Access • Arrayelements can be accessed in many ways Array access method Example array name and [ ] vals[2] = 17; pointer to array and [ ] valptr[2] = 17; array name and subscript arithmetic *(vals+2) = 17; pointer to array and subscript arithmetic *(valptr+2) = 17; 2/8/2017
  • 18.
    Array Access •Array notation •vals[i] • is equivalent to the pointer notation • *(vals + i) •No bounds checking performed on array access 2/8/2017
  • 19.
    Conti… int number[] ={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Values"; cout << "n number[0] : " << number[0]; cout << "n*pNumber : " << *pNumbers; ---------------------------------------------------------------------------Output Values number[0] : 31 *pNumber : 31 2/8/2017
  • 20.
    Example Conti… int number[]= { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "n Number : " << Number; cout << "npNumbers : " << pNumbers; cout << "nnValues"; cout << "n Number [0] : " << number[0]; cout << "npNumbers[0] : " << pNumbers[0]; cout << "n Number [1] : " << number[1]; cout << "npNumbers[1] : " << pNumbers[1]; Addresses Number : 1245020 pNumbers : 1245020 Values Number [0] : 31 pNumbers[0] : 31 Number [1] : 28 pNumbers[1] : 28 2/8/2017
  • 21.
    Examples… (Output :?) #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; for (int i = 0; i < MAX; i++) { cout << "Value of var[" << i << "] = "; cout << var[i] << endl; } return 0; } //Output: Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200 2/8/2017
  • 22.
    Examples … (Outputwith pointer : ?) #include <iostream> using namespace std; const int MAX = 3; int main () { int var[MAX] = {10, 100, 200}; int *ptr[MAX]; for (int i = 0; i < MAX; i++) { ptr[i] = &var[i]; // assign the address of integer. } for (int i = 0; i < MAX; i++) { cout << "Value of var[" << i << "] = "; cout << *ptr[i] << endl; } return 0; } //Output: Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200 2/8/2017
  • 23.
    Examples Conti… int number[]= { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int *pNumbers = Number; cout << "Addresses"; cout << "n Number : " << Number; cout << "npNumbers : " << pNumbers; cout << "n Number +1 : " << Number+1; cout << "npNumbers+1 : " << pNumbers+1; cout << "n Number +2 : " << Number+2; cout << "npNumbers+2 : " << pNumbers+2; Addresses Number : 1245020 pNumbers : 1245020 Number +1 : 1245024 pNumbers+1: 1245024 Number +2 : 1245028 pNumbers+2 : 1245028 2/8/2017
  • 24.
  • 25.
    Pointers as FunctionParameters • A pointer can be a parameter • Works like a reference parameter to allow change to argument from within function • A pointer parameter must be explicitly dereferenced to access the contents at that address • When to pass parameters by value, reference, and pointer @ http://www.cplusplus.com/articles/z6vU7k9E/ 2/8/2017
  • 26.
    Pointers as FunctionParameters • Requires: 1) asterisk * on parameter in prototype and heading void getNum(int *ptr); 2) asterisk * in body to dereference the pointer cin >> *ptr; 3) address as argument to the function getNum(&num); 2/8/2017
  • 27.
    Pointers as FunctionParameters void swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp; } int num1 = 2, num2 = -3; swap(&num1, &num2); 2/8/2017
  • 28.
    Functions and Pointers •A pointer variable can be passed as a parameter either by value or by reference • To make a pointer a reference parameter in a function heading, use &: void pointerParameters(int* &p, double *q) { . . . } 2/8/2017
  • 29.
    Pointers and FunctionReturn Values • A function can return a value of type pointer: int* testExp(...) { . . . } 2/8/2017
  • 30.
    Pointers to Constantsand Constant Pointers •Pointer to a constant: cannot change the value that is pointed at •Constant pointer: address in pointer cannot change once pointer is initialized 2/8/2017
  • 31.
    Pointers to Constant •Mustuse const keyword in pointer definition: const double taxRates[] = {0.65, 0.8, 0.75}; const double *ratePtr; •Use const keyword for pointers in function headers to protect data from modification from within function 2/8/2017
  • 32.
    Constant Pointers •Defined withconst keyword adjacent to variable name: int classSize = 24; int * const classPtr = &classSize; •Must be initialized when defined •Can be used without initialization as a function parameter • Initialized by argument when function is called • Function can receive different arguments on different calls •While the address in the pointer cannot change, the data at that address may be changed 2/8/2017
  • 33.
  • 34.
    Pointer Arithmetic • Somearithmetic operators can be used with pointers: • Increment and decrement operators ++, -- • Integers can be added to or subtracted from pointers using the operators +, -, +=, and -= • One pointer can be subtracted from another by using the subtraction operator - 2/8/2017
  • 35.
    Pointer Arithmetic Assume thevariable definitions int vals[]={4,7,11}; int *valptr = vals; Examples of use of ++ and -- valptr++; // points at 7 valptr--; // now points at 4 2/8/2017
  • 36.
    Pointer Arithmetic Assume thevariable definitions: int vals[]={4,7,11}; int *valptr = vals; Example of use of + to add an int to a pointer: cout << *(valptr + 2) This statement will print 11 2/8/2017
  • 37.
    Assume the variabledefinitions: int vals[]={4,7,11}; int *valptr = vals; Example of use of +=: valptr = vals; // points at 4 valptr += 2; // points at 11 Pointer Arithmetic 2/8/2017
  • 38.
    Assume the variabledefinitions int vals[] = {4,7,11}; int *valptr = vals; Example of pointer subtraction valptr += 2; cout << valptr - val; This statement prints 2: the number of ints between valptr and val Pointer Arithmetic 2/8/2017
  • 39.
  • 40.
    Initializing Pointer Variables •C++ does not automatically initialize variables • Pointer variables must be initialized if you do not want them to point to anything • Initialized using the constant value 0 • Called the null pointer • Example: p = 0; • Or, use the NULL named constant: • p = NULL; • The number 0 is the only number that can be directly assigned to a pointer variable 2/8/2017
  • 41.
    Initializing Pointers Conti… •Caninitialize to NULL or 0 (zero) • int *ptr = NULL; •Can initialize to addresses of other variables int num, *numPtr = &num; int val[ISIZE], *valptr = val; •Initial value must have correct type float cost; int *ptr = &cost; // won't work 2/8/2017
  • 42.
    Comparing Pointers •Relational operatorscan be used to compare addresses in pointers •Comparing addresses in pointers is not the same as comparing contents pointed at by pointers: if (ptr1 == ptr2) // compares // addresses if (*ptr1 == *ptr2) // compares // contents 2/8/2017
  • 43.
    Operations on PointerVariables • Assignment: value of one pointer variable can be assigned to another pointer of same type • Relational operations: two pointer variables of same type can be compared for equality, etc. • Some limited arithmetic operations: • Integer values can be added and subtracted from a pointer variable • Value of one pointer variable can be subtracted from another pointer variable 2/8/2017
  • 44.
    Operations on PointerVariables (cont'd.) • Examples: int *p, *q; p = q; • In this case, p == q will evaluate to true, and p != q will evaluate to false int *p double *q; • In this case, q++; increments value of q by 8, and p = p + 2; increments value of p by 8 2/8/2017
  • 45.
    Operations on PointerVariables (cont'd.) • Pointer arithmetic can be very dangerous • The program can accidentally access the memory locations of other variables and change their content without warning • Some systems might terminate the program with an appropriate error message • Always exercise extra care when doing pointer arithmetic 2/8/2017
  • 46.
    Dynamic Memory Allocation NEW& DELETE Operators 2/8/2017
  • 47.
    Stack & HeapMemory Stack • the stack grows and shrinks as functions push and pop local variables • there is no need to manage the memory yourself, variables are allocated and freed automatically • the stack has size limits • stack variables only exist while the function that created them, is running • The Heap 2/8/2017
  • 48.
    Stack & HeapMemory Stack • very fast access • don't have to explicitly de- allocate variables • space is managed efficiently by CPU, memory will not become fragmented • local variables only • limit on stack size (OS- dependent) • variables cannot be resized Heap • variables can be accessed globally • no limit on memory size • (relatively) slower access • no guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed • you must manage memory (you're in charge of allocating and freeing variables) • variables can be resized using realloc() 2/8/2017
  • 49.
    Dynamic Variables • Dynamicvariables: created during execution • C++ creates dynamic variables using pointers • Two operators, new and delete, to create and destroy dynamic variables • new and delete are reserved words 2/8/2017
  • 50.
    Operator new • newhas two forms: • where intExp is any expression evaluating to a positive integer • new allocates memory (a variable) of the designated type and returns a pointer to it • The address of the allocated memory • The allocated memory is uninitialized 2/8/2017
  • 51.
    Operator new (cont'd.) •The statement: p = &x; • Stores address of x in p • However, no new memory is allocated • The statement: p = new int; • Creates a variable during program execution somewhere in memory, and stores the address of the allocated memory in p • To access allocated memory: *p 2/8/2017
  • 52.
  • 53.
    Operator new (cont'd.) •new allocates memory space of a specific type and returns the (starting) address of the allocated memory space • If new is unable to allocate the required memory space, then it throws bad_alloc exception • If this exception is not handled, it terminates the program with an error message 2/8/2017
  • 54.
  • 55.
    Operator delete (cont'd.) •To avoid memory leak, when a dynamic variable is no longer needed, destroy it • Deallocate its memory • delete is used to destroy dynamic variables • Syntax: • Tip: to avoid dangling pointers, set variable to NULL afterwards 2/8/2017
  • 56.
    Dynamic Arrays • Dynamicarray: array created during the execution of a program • Example: int *p; p = new int[10]; *p = 25; p++; //to point to next array component *p = 35; stores 25 into the first memory location stores 35 into the second memory location 2/8/2017
  • 57.
    Dynamic Arrays (cont'd.) •C++ allows us to use array notation to access these memory locations • The statements: p[0] = 25; p[1] = 35; store 25 and 35 into the first and second array components, respectively 2/8/2017
  • 58.
  • 59.
  • 60.
    Dynamic Arrays (cont'd.) •The value of list (1000) is constant • Cannot be altered during program execution • The increment and decrement operations cannot be applied to list • If p is a pointer variable of type int, then: p = list; copies the value of list, the base address of the array, into p • We can perform ++ and -- operations on p • An array name is a constant pointer 2/8/2017
  • 61.
  • 62.
    Dynamic Two-Dimensional Arrays •You can create dynamic multidimensional arrays • Examples: declares board to be an array of four pointers wherein each pointer is of type int creates the rows of board declares board to be a pointer to a pointer 2/8/2017
  • 63.
    Pointer to Pointer(Multiple Indirection) • Define a pointer to a pointer • First pointer contains the address of the second pointer • Declared with ** like int **var; • Also called “Double Pointer” e.g. int **ipp; int i = 5, j = 6; k = 7; int *ip1 = &i, *ip2 = &j; ipp = &ip1; 2/8/2017
  • 64.
    Double Pointer #include <iostream> usingnamespace std; int main () { int var; int *ptr; int **pptr; var = 3000; // take the address of var ptr = &var; // take the address of ptr using address of operator & pptr = &ptr; // take the value using pptr cout << "Value of var :" << var << endl; cout << "Value available at *ptr :" << *ptr << endl; cout << "Value available at **pptr :" << **pptr << endl; return 0; } 2/8/2017
  • 65.
    Double Pointer &Dynamic 2D Array You may create fully dynamic two dimensional array using 2d pointer. ------------------------------------- //Create your pointer int **ptr; //Assign first dimension ptr = new int*[5]; //Assign second dimension for(int i = 0; i < 5; i++) ptr[i] = new int[5]; 2/8/2017
  • 66.
  • 67.
    Shallow vs. DeepCopy & Pointers 2/8/2017
  • 68.
    Shallow versus DeepCopy and Pointers • Assume some data is stored in the array: • If we execute: 2/8/2017
  • 69.
    Shallow versus DeepCopy and Pointers (cont'd.) • Shallow copy: two or more pointers of the same type point to the same memory • They point to the same data 2/8/2017
  • 70.
    Shallow versus DeepCopy and Pointers (cont'd.) • Deep copy: two or more pointers have their own data 2/8/2017
  • 71.
    Void Pointer • Exception:pointer to void (type void *) • Generic pointer, represents any type • No casting needed to convert a pointer to void pointer • void pointers cannot be dereferenced int nValue; float fValue; double sValue; void *pVoid; pVoid = &nValue; // valid pVoid = &fValue; // valid pVoid = &sValue; // valid int nValue = 5; void *pVoid = &nValue; // can not dereference pVoid because it is a void pointer int *pInt = static_cast<int*>(pVoid); // cast from void* to int* cout << *pInt << endl; // can dereference pInt 2/8/2017
  • 72.
    sizeof() of operator •sizeof • Unary operator returns size of operand in bytes • For arrays, sizeof returns ( size of 1 element ) * ( number of elements ) • If sizeof( int ) = 4, then int myArray[10]; cout << sizeof(myArray); will print 40 • sizeof can be used with • Variable names • Type names • Constant values 2/8/2017
  • 73.
  • 74.
  • 75.
    Home Tasks …! ! ! • Count how many numbers are stored in a file. Then create an array to store those numbers and sort. • Implement a sorting algorithm and use swap(int *, int *) to swap the values of array elements. • Use sizeof(…) to find the size of simple variables and array. Example is give in examples section • Create a text file which has different number of elements in each row. Then create an compatible 2D array to read and store the values. Perform different operations. 2/8/2017
  • 76.
    Example – I 1// Fig. 5.10: fig05_10.cpp 2 // Converting lowercase letters to uppercase letters 3 // using a non-constant pointer to non-constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <cctype> // prototypes for islower and toupper 10 11 void convertToUppercase( char * ); 12 13 int main() 14 { 15 char phrase[] = "characters and $32.98"; 16 17 cout << "The phrase before conversion is: " << phrase; 18 convertToUppercase( phrase ); 19 cout << "nThe phrase after conversion is: " 20 << phrase << endl; 21 22 return 0; // indicates successful termination 23 24 } // end main 25 2/8/2017
  • 77.
    Example – I… 26// convert string to uppercase letters 27 void convertToUppercase( char *sPtr ) 28 { 29 while ( *sPtr != '0' ) { // current character is not '0' 30 31 if ( islower( *sPtr ) ) // if character is lowercase, 32 *sPtr = toupper( *sPtr ); // convert to uppercase 33 34 ++sPtr; // move sPtr to next character in string 35 36 } // end while 37 38 } // end function convertToUppercase The phrase before conversion is: characters and $32.98 The phrase after conversion is: CHARACTERS AND $32.98 Parameter sPtr nonconstant pointer to nonconstant data Function islower returns true if character is lowercase Function toupper returns corresponding uppercase character if original character lowercase; otherwise toupper returns original (uppercase) character When operator ++ applied to pointer that points to array, memory address stored in pointer modified to point to next element of array. 2/8/2017
  • 78.
    Example – II 1// Fig. 5.11: fig05_11.cpp 2 // Printing a string one character at a time using 3 // a non-constant pointer to constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 void printCharacters( const char * ); 10 11 int main() 12 { 13 char phrase[] = "print characters of a string"; 14 15 cout << "The string is:n"; 16 printCharacters( phrase ); 17 cout << endl; 18 19 return 0; // indicates successful termination 20 21 } // end main 22 2/8/2017
  • 79.
    Example – II… 23// sPtr cannot modify the character to which it points, 24 // i.e., sPtr is a "read-only" pointer 25 void printCharacters( const char *sPtr ) 26 { 27 for ( ; *sPtr != '0'; sPtr++ ) // no initialization 28 cout << *sPtr; 29 30 } // end function printCharacters The string is: print characters of a string sPtr is nonconstant pointer to constant data; cannot modify character to which sPtr points. 2/8/2017
  • 80.
    Example – III 1// Fig. 5.11: fig05_11.cpp 2 // Printing a string one character at a time using 3 // a non-constant pointer to constant data. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 void printCharacters( const char * ); 10 11 int main() 12 { 13 char phrase[] = "print characters of a string"; 14 15 cout << "The string is:n"; 16 printCharacters( phrase ); 17 cout << endl; 18 19 return 0; // indicates successful termination 20 21 } // end main 22 2/8/2017
  • 81.
    Example – IV 1// Fig. 5.12: fig05_12.cpp 2 // Attempting to modify data through a 3 // non-constant pointer to constant data. 4 5 void f( const int * ); // prototype 6 7 int main() 8 { 9 int y; 10 11 f( &y ); // f attempts illegal modification 12 13 return 0; // indicates successful termination 14 15 } // end main 16 17 // xPtr cannot modify the value of the variable 18 // to which it points 19 void f( const int *xPtr ) 20 { 21 *xPtr = 100; // error: cannot modify a const object 22 23 } // end function f d:cpphtp4_examplesch05Fig05_12.cpp(21) : error C2166: l-value specifies const object Parameter is nonconstant pointer to constant data. Pass address of int variable y to attempt illegal modification. Attempt to modify const object pointed to by xPtr. Error produced when attempting to compile. 2/8/2017
  • 82.
    Example – V 1// Fig. 5.13: fig05_13.cpp 2 // Attempting to modify a constant pointer to 3 // non-constant data. 4 5 int main() 6 { 7 int x, y; 8 9 // ptr is a constant pointer to an integer that can 10 // be modified through ptr, but ptr always points to the 11 // same memory location. 12 int * const ptr = &x; 13 14 *ptr = 7; // allowed: *ptr is not const 15 ptr = &y; // error: ptr is const; cannot assign new address 16 17 return 0; // indicates successful termination 18 19 } // end main d:cpphtp4_examplesch05Fig05_13.cpp(15) : error C2166: l-value specifies const object ptr is constant pointer to integer. Can modify x (pointed to by ptr) since x not constant. Cannot modify ptr to point to new address since ptr is constant. Line 15 generates compiler error by attempting to assign new address to constant pointer. 2/8/2017
  • 83.
    1 // Fig.5.14: fig05_14.cpp 2 // Attempting to modify a constant pointer to constant data. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 int x = 5, y; 11 12 // ptr is a constant pointer to a constant integer. 13 // ptr always points to the same location; the integer 14 // at that location cannot be modified. 15 const int *const ptr = &x; 16 17 cout << *ptr << endl; 18 19 *ptr = 7; // error: *ptr is const; cannot assign new value 20 ptr = &y; // error: ptr is const; cannot assign new address 21 22 return 0; // indicates successful termination 23 24 } // end main ptr is constant pointer to integer constant. Cannot modify x (pointed to by ptr) since *ptr declared constant. Cannot modify ptr to point to new address since ptr is constant. d:cpphtp4_examplesch05Fig05_14.cpp(19) : error C2166: l-value specifies const object d:cpphtp4_examplesch05Fig05_14.cpp(20) : error C2166: l-value specifies const object Line 19 generates compiler error by attempting to modify constant object. Line 20 generates compiler error by attempting to assign new address to constant pointer. Example–VI 2/8/2017
  • 84.
    Example –VII 1 //Fig. 5.16: fig05_16.cpp 2 // Sizeof operator when used on an array name 3 // returns the number of bytes in the array. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 size_t getSize( double * ); // prototype 10 11 int main() 12 { 13 double array[ 20 ]; 14 15 cout << "The number of bytes in the array is " 16 << sizeof( array ); 17 18 cout << "nThe number of bytes returned by getSize is " 19 << getSize( array ) << endl; 20 21 return 0; // indicates successful termination 22 23 } // end main 24 Operator sizeof applied to an array returns total number of bytes in array. Function getSize returns number of bytes used to store array address. 2/8/2017
  • 85.
    Example – VIII 20cout << "sizeof c = " << sizeof c 21 << "tsizeof(char) = " << sizeof( char ) 22 << "nsizeof s = " << sizeof s 23 << "tsizeof(short) = " << sizeof( short ) 24 << "nsizeof i = " << sizeof i 25 << "tsizeof(int) = " << sizeof( int ) 26 << "nsizeof l = " << sizeof l 27 << "tsizeof(long) = " << sizeof( long ) 28 << "nsizeof f = " << sizeof f 29 << "tsizeof(float) = " << sizeof( float ) 30 << "nsizeof d = " << sizeof d 31 << "tsizeof(double) = " << sizeof( double ) 32 << "nsizeof ld = " << sizeof ld 33 << "tsizeof(long double) = " << sizeof( long double ) 34 << "nsizeof array = " << sizeof array 35 << "nsizeof ptr = " << sizeof ptr 36 << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main Operator sizeof can be used on variable name. Operator sizeof can be used on type name. sizeof c = 1 sizeof(char) = 1 sizeof s = 2 sizeof(short) = 2 sizeof i = 4 sizeof(int) = 4 sizeof l = 4 sizeof(long) = 4 sizeof f = 4 sizeof(float) = 4 sizeof d = 8 sizeof(double) = 8 sizeof ld = 8 sizeof(long double) = 8 sizeof array = 80 sizeof ptr = 42/8/2017
  • 86.
    Example – IX 1// Fig. 5.25: fig05_25.cpp 2 // Multipurpose sorting program using function pointers. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 // prototypes 14 void bubble( int [], const int, bool (*)( int, int ) ); 15 void swap( int * const, int * const ); 16 bool ascending( int, int ); 17 bool descending( int, int ); 18 19 int main() 20 { 21 const int arraySize = 10; 22 int order; 23 int counter; 24 int a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 25 Parameter is pointer to function that receives two integer parameters and returns bool result. 2/8/2017
  • 87.
    Example – IX… 26cout << "Enter 1 to sort in ascending order,n" 27 << "Enter 2 to sort in descending order: "; 28 cin >> order; 29 cout << "nData items in original ordern"; 30 31 // output original array 32 for ( counter = 0; counter < arraySize; counter++ ) 33 cout << setw( 4 ) << a[ counter ]; 34 35 // sort array in ascending order; pass function ascending 36 // as an argument to specify ascending sorting order 37 if ( order == 1 ) { 38 bubble( a, arraySize, ascending ); 39 cout << "nData items in ascending ordern"; 40 } 41 42 // sort array in descending order; pass function descending 43 // as an agrument to specify descending sorting order 44 else { 45 bubble( a, arraySize, descending ); 46 cout << "nData items in descending ordern"; 47 } 48 2/8/2017
  • 88.
    Example – IX… 49// output sorted array 50 for ( counter = 0; counter < arraySize; counter++ ) 51 cout << setw( 4 ) << a[ counter ]; 52 53 cout << endl; 54 55 return 0; // indicates successful termination 56 57 } // end main 58 59 // multipurpose bubble sort; parameter compare is a pointer to 60 // the comparison function that determines sorting order 61 void bubble( int work[], const int size, 62 bool (*compare)( int, int ) ) 63 { 64 // loop to control passes 65 for ( int pass = 1; pass < size; pass++ ) 66 67 // loop to control number of comparisons per pass 68 for ( int count = 0; count < size - 1; count++ ) 69 70 // if adjacent elements are out of order, swap them 71 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) 72 swap( &work[ count ], &work[ count + 1 ] ); compare is pointer to function that receives two integer parameters and returns bool result. Parentheses necessary to indicate pointer to function Call passed function compare; dereference pointer to execute function. 2/8/2017
  • 89.
    Example – IX… 73 74} // end function bubble 75 76 // swap values at memory locations to which 77 // element1Ptr and element2Ptr point 78 void swap( int * const element1Ptr, int * const element2Ptr ) 79 { 80 int hold = *element1Ptr; 81 *element1Ptr = *element2Ptr; 82 *element2Ptr = hold; 83 84 } // end function swap 85 86 // determine whether elements are out of order 87 // for an ascending order sort 88 bool ascending( int a, int b ) 89 { 90 return b < a; // swap if b is less than a 91 92 } // end function ascending 93 2/8/2017
  • 90.
    Example – IX… 94// determine whether elements are out of order 95 // for a descending order sort 96 bool descending( int a, int b ) 97 { 98 return b > a; // swap if b is greater than a 99 100 } // end function descending Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 2 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in descending order 89 68 45 37 12 10 8 6 4 2 2/8/2017
  • 91.
    Example – X 1// Fig. 5.26: fig05_26.cpp 2 // Demonstrating an array of pointers to functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 // function prototypes 10 void function1( int ); 11 void function2( int ); 12 void function3( int ); 13 14 int main() 15 { 16 // initialize array of 3 pointers to functions that each 17 // take an int argument and return void 18 void (*f[ 3 ])( int ) = { function1, function2, function3 }; 19 20 int choice; 21 22 cout << "Enter a number between 0 and 2, 3 to end: "; 23 cin >> choice; 24 Array initialized with names of three functions; function names are pointers. 2/8/2017
  • 92.
    Example – X… 25// process user's choice 26 while ( choice >= 0 && choice < 3 ) { 27 28 // invoke function at location choice in array f 29 // and pass choice as an argument 30 (*f[ choice ])( choice ); 31 32 cout << "Enter a number between 0 and 2, 3 to end: "; 33 cin >> choice; 34 } 35 36 cout << "Program execution completed." << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was callednn"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array. 2/8/2017
  • 93.
    Example – X… 49void function2( int b ) 50 { 51 cout << "You entered " << b 52 << " so function2 was callednn"; 53 54 } // end function2 55 56 void function3( int c ) 57 { 58 cout << "You entered " << c 59 << " so function3 was callednn"; 60 61 } // end function3 Enter a number between 0 and 2, 3 to end: 0 You entered 0 so function1 was called Enter a number between 0 and 2, 3 to end: 1 You entered 1 so function2 was called Enter a number between 0 and 2, 3 to end: 2 You entered 2 so function3 was called Enter a number between 0 and 2, 3 to end: 3 Program execution completed. 2/8/2017