In the previous article (pointing to a function pointer example), we mentioned that there are two logically inconsistent syntax rules for using a function pointer to implement such an operation, and we will discuss it in the form of a question, in the past few days, I have read c primer plus and found a reasonable explanation. See the following example:
void ToUpper(char *);void ToLower(char *);void (*pf)(char *);char mis[] = "Nina Metier";pf = ToUpper;(*pf)(mis);pf = ToLower;pf(mis);
Each method seems reasonable. Method 1: because pf points to the toupper function, * PF is the toupper function, so the expression (* PF) (MIS) is the same as toupper (MIS. From the toupper and PF statements, we can see that toupper and (* PF) are hierarchical. Method 2: because the function name is a pointer, pointers and function names can be used interchangeably. Therefore, PF (MIS) is the same as tolower (MIS. From the assignment statement of PF, we can see that PF and tolower are equivalent. Why? This is because of C's historical reasons.
Historically, Bell Labs's C and Unix developers adopted the first point of view, while Berkeley's Unix extension adopted the second point of view. The second form is not allowed for K & r c. However, to maintain compatibility with modern code, ansi c accepts all their seating equivalent forms. I installed B for so long because I still don't know the reason before class today, and this problem has been bothering me. The stone finally landed, but I was a little disappointed.
In order not to be so bloody, it will end. Here is another example of using a function pointer.
# Include <stdio. h> # include <string. h> # include <ctype. h> char showmenu (void); void eatline (void); // read to the end of the row void show (void (* FP) (char *), char * Str ); void toupper (char *); // converts a string to an upper-case void tolower (char *); // converts a string to a lower-case void transpose (char *); // convert the case to void dummy (char *); // do not change the string int main () {char line [81]; char copy [81]; char choice; void (* pfun) (char *); // points to a function that accepts a char * parameter and does not return the puts ("enter a string (empty Line to quit): "); While (gets (line )! = NULL & line [0]! = '\ 0') {While (choice = showmenu ())! = 'N') {Switch (choice) // The switch statement is used to set the pointer {Case 'U': pfun = toupper; break; Case 'l': pfun = tolower; break; case 'T': pfun = transpose; break; Case 'O': pfun = dummy; break;} strcpy (copy, line); // show () create a copy of the string copy show (pfun, copy); // use the user-selected function} puts ("enter a string (empty line to quit ):");} puts ("Bye! "); Return 0;} Char showmenu (void) {char ans; puts (" Enter menu choice: "); puts (" U) uppercase L) lowercase "); puts ("t) transposed case o) original case"); puts ("N) Next string"); ans = getchar (); // obtain the user's response ans = tolower (ANS); // convert the case-sensitive eatline (); // remove the remaining part of the row while (strchr ("ulton", ANS) = NULL) {puts ("Please enter a U, L, t, O, N:"); ans = tolower (getchar (); eatline ();} return ans;} void eatline (void) {While (getchar ()! = '\ N') continue;} void toupper (char * Str) {While (* Str) {* STR = (toupper (* Str); STR ++ ;}} void tolower (char * Str) {While (* Str) {* STR = (tolower (* Str); STR ++ ;}} void transpose (char * Str) {While (* Str) {If (islower (* Str) * STR = toupper (* Str); else if (isupper (* Str )) * STR = tolower (* Str); STR ++ ;}} void dummy (char * Str) {}void show (void (* FP) (char *), char * Str) {(* FP) (STR); // apply the user-selected function to STR puts (STR); // output STR}
Note that the toupper (), tolower (), transpose (), and dummy () functions are of the same type. Therefore, all four functions can be assigned to the pfun pointer. This program uses pfun as the show () parameter, but you can also directly use any of the four function names as the parameter, just like show (transpose, copy.
As for menu processing, the showmenu () function provides several techniques. First, the Code:
Ans = getchar (); // obtain the user's response ans = tolower (ANS); // converts the case sensitivity.
And:
ans = tolower(getchar());
Two methods are provided. Both methods can convert user input into a case-sensitive format, so that you do not need to check 'U' or 'u.
The function eatline () removes the remainder of the input line, which is useful in two aspects. First, you need to enter a selection. The user will enter a letter and press the Enter key, which will generate a line break. If this line break is not removed beforehand, it will be read as the next user response. Second, assume that the user inputs the entire word uppercase instead of U as the response. Without the eatline () function, the program treats each character of the word uppercase as a separate response. With eatline (), the program only processes U and discards the rest of the input line.
The showmenu () function is designed to return only the correct choice to the main function. To complete this task, the program uses the standard library function strchr () in the string. h header file ():
while(strchr("ulton", ans) == NULL)
In the string "ulton", this function finds the first occurrence position of the character ANS and returns a pointer to this position. If this character is not found, the function returns a null pointer. Therefore, the while loop judgment condition has the same effect as the judgment condition, but it is more convenient to use:
while(ans != 'n' && ans != 'l' && ans != 't' && ans != 'o' && ans != 'n')
The more choices you need to check, the more convenient it is to use strchr.
We hope that the two slightly larger examples described in this article and the previous article can be used to clarify some concepts of function pointers. I would like to thank C primer plus and Stephen Prata, author of the book.