
5.11 Function Pointers • Pointers to functions • Contain address of function • Similar to how array name is address of first element • Function name is starting address of code that defines function • Function pointers can be • Passed to functions • Returned from functions • Stored in arrays • Assigned to other function pointers
5.11 Function Pointers • Calling functions using pointers • Assume parameter: • bool ( *compare ) ( int, int ) • Execute function with either • ( *compare ) ( int1, int2 ) • Dereference pointer to function to execute OR • compare( int1, int2 ) • Could be confusing • User may think compare name of actual function in program
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 constintarraySize = 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. fig05_25.cpp(1 of 5)
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 order\n"; 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 order\n"; 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 order\n"; 47 } 48 fig05_25.cpp(2 of 5)
49 // output sorted array 50 for ( counter = 0; counter < arraySize; counter++ ) 51 cout << setw( 4 ) << a[ counter ]; 52 53 cout << endl; 54 55 return0; // 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. fig05_25.cpp(3 of 5)
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 fig05_25.cpp(4 of 5)
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 fig05_25.cpp(5 of 5)fig05_25.cppoutput (1 of 1) 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
5.11 Function Pointers • Arrays of pointers to functions • Menu-driven systems • Pointers to each function stored in array of pointers to functions • All functions must have same return type and same parameter types • Menu choice subscript into array of function pointers
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. fig05_26.cpp(1 of 3)
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 return0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was called\n\n"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array. fig05_26.cpp(2 of 3)
49 void function2( int b ) 50 { 51 cout << "You entered " << b 52 << " so function2 was called\n\n"; 53 54 } // end function2 55 56 void function3( int c ) 57 { 58 cout << "You entered " << c 59 << " so function3 was called\n\n"; 60 61 } // end function3 fig05_26.cpp(3 of 3)fig05_26.cppoutput (1 of 1) 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.
Memory It is the job of the Operating System to • Manage the allocation of memory to processes • Keep track of what memory/addresses each process is allowed to access • Reserve portion of memory for use by the OS • Enforce protection of memory space of each process
Pointer – a variable whose value is a memory address • Pointee – the value in memory whose address is stored in a pointer – the pointee is the target of the pointer. • A pointer may or may not have a target. Pointers without targets should be set to 0 or NULL.
int x = 4, y = 99; int *p1, *p2; p1 = &x; p2 = &y; *p1 = 3; cout << *p1 << ““<< *p2; p2 = p1; cout << *p1 << ““<< *p2;
float i, x, *p, *q; p = &i; *p = 10.0; q = &x; *q = 8.6; cout << x << endl; cout << I << endl; *p = 9.5; p = q; q = &i; cout << *p <<endl; cout << i <<endl; cout << x << endl; cout << *q << endl;
int *p, *q, *r, *s; int a, b, c, d[10]; p = &a; q = &b; *q = 98; *p = 76; q = p; cout <<*p << endl; cout << *q << endl; r = &d[0]; //note this is the same as saying r=d, which is also valid for (int i =0; i < 10; i++) r[i] = i; p = r; ++p; s= p; ++s; cout << *r << endl; cout << *q << endl; cout << *p <<endl; cout << *s <<endl;
Dynamic Allocation Using the new command: int *p1 = new int; int *p2 = new double[1000]; for (i = 0; i < 1000; i++) p2[i] = 2*i; delete p1; delete [] p2;
int *p, *q, *r, *s; p = new int; *p = 76; cout <<*p << endl; r = new int [10]; //note this is the same as saying r=d, which is also valid for (int i =0; i < 10; i++) r[i] = i; q = r; ++q; s= q; ++s; cout << *r << endl; cout << *q << endl; cout << *p <<endl; cout << *s <<endl;
Memory Leak int *p1 = new int; int *p2 = new double[1000]; for (i = 0; i < 1000; i++) p2[i] = 2*i; p2 = p1; //NOW THE ARRAY IS LOST delete p1; delete [] p2;
5.12.1 Fundamentals of Characters and Strings • Character constant • Integer value represented as character in single quotes • 'z' is integer value of z • 122 in ASCII • String • Series of characters treated as single unit • Can include letters, digits, special characters +, -, * ... • String literal (string constants) • Enclosed in double quotes, for example: "I like C++" • Array of characters, ends with null character '\0' • String is constant pointer • Pointer to string’s first character • Like arrays
5.12.1 Fundamentals of Characters and Strings • String assignment • Character array • char color[] = "blue"; • Creates 5 element char array color • last element is '\0' • Variable of type char * • char *colorPtr = "blue"; • Creates pointer colorPtr to letter b in string “blue” • “blue” somewhere in memory • Alternative for character array • char color[] = { ‘b’, ‘l’, ‘u’, ‘e’, ‘\0’ };
5.12.1 Fundamentals of Characters and Strings • Reading strings • Assign input to character array word[ 20 ] cin >> word • Reads characters until whitespace or EOF • String could exceed array size cin >> setw( 20 ) >> word; • Reads 19 characters (space reserved for '\0')
5.12.1 Fundamentals of Characters and Strings • cin.getline • Read line of text • cin.getline( array, size, delimiter ); • Copies input into specified array until either • One less than size is reached • delimiter character is input • Example char sentence[ 80 ]; cin.getline( sentence, 80, '\n' );
5.12.2 String Manipulation Functions of the String-handling Library • String handling library <cstring> provides functions to • Manipulate string data • Compare strings • Search strings for characters and other strings • Tokenize strings (separate strings into logical pieces)
5.12.2 String Manipulation Functions of the String-handling Library
5.12.2 String Manipulation Functions of the String-handling Library
5.12.2 String Manipulation Functions of the String-handling Library • Copying strings • char *strcpy( char *s1, const char *s2 ) • Copies second argument into first argument • First argument must be large enough to store string and terminating null character • char *strncpy( char *s1, const char *s2, size_t n ) • Specifies number of characters to be copied from string into array • Does not necessarily copy terminating null character
1 // Fig. 5.28: fig05_28.cpp 2 // Using strcpy and strncpy. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cstring> // prototypes for strcpy and strncpy 9 10 int main() 11 { 12 char x[] = "Happy Birthday to You"; 13 char y[ 25 ]; 14 char z[ 15 ]; 15 16 strcpy( y, x ); // copy contents of x into y 17 18 cout << "The string in array x is: " << x 19 << "\nThe string in array y is: " << y << '\n'; 20 21 // copy first 14 characters of x into z 22 strncpy( z, x, 14 ); // does not copy null character 23 z[ 14 ] = '\0'; // append '\0' to z's contents 24 25 cout << "The string in array z is: " << z << endl; <cstring> contains prototypes for strcpy and strncpy. Copy entire string in array x into array y. Copy first 14 characters of array x into array y. Note that this does not write terminating null character. Append terminating null character. fig05_28.cpp(1 of 2)
26 27 return0; // indicates successful termination 28 29 } // end main String to copy. Copied string using strcpy. Copied first 14 characters using strncpy. fig05_28.cpp(2 of 2)fig05_28.cppoutput (1 of 1) The string in array x is: Happy Birthday to You The string in array y is: Happy Birthday to You The string in array z is: Happy Birthday
5.12.2 String Manipulation Functions of the String-handling Library • Concatenating strings • char *strcat( char *s1, const char *s2 ) • Appends second argument to first argument • First character of second argument replaces null character terminating first argument • Ensure first argument large enough to store concatenated result and null character • char *strncat( char *s1, const char *s2, size_t n ) • Appends specified number of characters from second argument to first argument • Appends terminating null character to result
1 // Fig. 5.29: fig05_29.cpp 2 // Using strcat and strncat. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cstring> // prototypes for strcat and strncat 9 10 int main() 11 { 12 char s1[ 20 ] = "Happy "; 13 char s2[] = "New Year "; 14 char s3[ 40 ] = ""; 15 16 cout << "s1 = " << s1 << "\ns2 = " << s2; 17 18 strcat( s1, s2 ); // concatenate s2 to s1 19 20 cout << "\n\nAfter strcat(s1, s2):\ns1 = " << s1 21 << "\ns2 = " << s2; 22 23 // concatenate first 6 characters of s1 to s3 24 strncat( s3, s1, 6 ); // places '\0' after last character 25 <cstring> contains prototypes for strcat and strncat. Append s2 to s1. Append first 6 characters of s1 to s3. fig05_29.cpp(1 of 2)
26 cout << "\n\nAfter strncat(s3, s1, 6):\ns1 = " << s1 27 << "\ns3 = " << s3; 28 29 strcat( s3, s1 ); // concatenate s1 to s3 30 cout << "\n\nAfter strcat(s3, s1):\ns1 = " << s1 31 << "\ns3 = " << s3 << endl; 32 33 return0; // indicates successful termination 34 35 } // end main Append s1 to s3. fig05_29.cpp(2 of 2)fig05_29.cppoutput (1 of 1) s1 = Happy s2 = New Year After strcat(s1, s2): s1 = Happy New Year s2 = New Year After strncat(s3, s1, 6): s1 = Happy New Year s3 = Happy After strcat(s3, s1): s1 = Happy New Year s3 = Happy Happy New Year
5.12.2 String Manipulation Functions of the String-handling Library • Comparing strings • Characters represented as numeric codes • Strings compared using numeric codes • Character codes / character sets • ASCII • “American Standard Code for Information Interchage” • EBCDIC • “Extended Binary Coded Decimal Interchange Code”
5.12.2 String Manipulation Functions of the String-handling Library • Comparing strings • int strcmp( const char *s1, const char *s2 ) • Compares character by character • Returns • Zero if strings equal • Negative value if first string less than second string • Positive value if first string greater than second string • int strncmp( const char *s1, const char *s2, size_t n ) • Compares up to specified number of characters • Stops comparing if reaches null character in one of arguments
1 // Fig. 5.30: fig05_30.cpp 2 // Using strcmp and strncmp. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::setw; 11 12 #include <cstring> // prototypes for strcmp and strncmp 13 14 int main() 15 { 16 char *s1 = "Happy New Year"; 17 char *s2 = "Happy New Year"; 18 char *s3 = "Happy Holidays"; 19 20 cout << "s1 = " << s1 << "\ns2 = " << s2 21 << "\ns3 = " << s3 << "\n\nstrcmp(s1, s2) = " 22 << setw( 2 ) << strcmp( s1, s2 ) 23 << "\nstrcmp(s1, s3) = " << setw( 2 ) 24 << strcmp( s1, s3 ) << "\nstrcmp(s3, s1) = " 25 << setw( 2 ) << strcmp( s3, s1 ); <cstring> contains prototypes for strcmp and strncmp. Compare s1 and s2. Compare s3 and s1. Compare s1 and s3. fig05_30.cpp(1 of 2)
26 27 cout << "\n\nstrncmp(s1, s3, 6) = " << setw( 2 ) 28 << strncmp( s1, s3, 6 ) << "\nstrncmp(s1, s3, 7) = " 29 << setw( 2 ) << strncmp( s1, s3, 7 ) 30 << "\nstrncmp(s3, s1, 7) = " 31 << setw( 2 ) << strncmp( s3, s1, 7 ) << endl; 32 33 return0; // indicates successful termination 34 35 } // end main Compare up to 6 characters of s1 and s3. Compare up to 7 characters of s1 and s3. Compare up to 7 characters of s3 and s1. fig05_30.cpp(2 of 2)fig05_30.cppoutput (1 of 1) s1 = Happy New Year s2 = Happy New Year s3 = Happy Holidays strcmp(s1, s2) = 0 strcmp(s1, s3) = 1 strcmp(s3, s1) = -1 strncmp(s1, s3, 6) = 0 strncmp(s1, s3, 7) = 1 strncmp(s3, s1, 7) = -1
5.12.2 String Manipulation Functions of the String-handling Library • Tokenizing • Breaking strings into tokens, separated by delimiting characters • Tokens usually logical units, such as words (separated by spaces) • "This is my string" has 4 word tokens (separated by spaces) • char *strtok( char *s1, const char *s2 ) • Multiple calls required • First call contains two arguments, string to be tokenized and string containing delimiting characters • Finds next delimiting character and replaces with null character • Subsequent calls continue tokenizing • Call with first argument NULL
1 // Fig. 5.31: fig05_31.cpp 2 // Using strtok. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cstring> // prototype for strtok 9 10 int main() 11 { 12 char sentence[] = "This is a sentence with 7 tokens"; 13 char *tokenPtr; 14 15 cout << "The string to be tokenized is:\n" << sentence 16 << "\n\nThe tokens are:\n\n"; 17 18 // begin tokenization of sentence 19 tokenPtr = strtok( sentence, " " ); 20 <cstring> contains prototype for strtok. First call to strtok begins tokenization. fig05_31.cpp(1 of 2)
21 // continue tokenizing sentence until tokenPtr becomes NULL 22 while ( tokenPtr != NULL ) { 23 cout << tokenPtr << '\n'; 24 tokenPtr = strtok( NULL, " " ); // get next token 25 26 } // end while 27 28 cout << "\nAfter strtok, sentence = " << sentence << endl; 29 30 return0; // indicates successful termination 31 32 } // end main Subsequent calls to strtok with NULL as first argument to indicate continuation. fig05_31.cpp(2 of 2)
The string to be tokenized is: This is a sentence with 7 tokens The tokens are: This is a sentence with 7 tokens After strtok, sentence = This fig05_31.cppoutput (1 of 1)
5.12.2 String Manipulation Functions of the String-handling Library • Determining string lengths • size_t strlen( const char *s ) • Returns number of characters in string • Terminating null character not included in length
1 // Fig. 5.32: fig05_32.cpp 2 // Using strlen. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <cstring> // prototype for strlen 9 10 int main() 11 { 12 char *string1 = "abcdefghijklmnopqrstuvwxyz"; 13 char *string2 = "four"; 14 char *string3 = "Boston"; 15 16 cout << "The length of \"" << string1 17 << "\" is " << strlen( string1 ) 18 << "\nThe length of \"" << string2 19 << "\" is " << strlen( string2 ) 20 << "\nThe length of \"" << string3 21 << "\" is " << strlen( string3 ) << endl; 22 23 return0; // indicates successful termination 24 25 } // end main <cstring> contains prototype for strlen. Using strlen to determine length of strings. fig05_32.cpp(1 of 1)
The length of "abcdefghijklmnopqrstuvwxyz" is 26 The length of "four" is 4 The length of "Boston" is 6 fig05_32.cppoutput (1 of 1)
Review Pointers and Strings : What does the following code do? void POKEMON(char *PIKACHU, char *ASH) { while (*PIKACHU++ == *ASH++) ; return; } IMPLEMENT IT!