We have already seen how a function pointer can be used to point to a function. If such a pointer is used as a parameter to another function say sort(), the function sort() can be invoked and passed different helper functions such as stringCompare(), numericCompare(), and dateCompare(), as per different cases of program logic. The formal parameter compare in sort() can then work upon the different helper functions passed to it. Here is a code snippet to illustrate this:
main() { ... int stringCompare(char *x, char *y); int numericCompare(char *x, char *y); int dateCompare(char *x, char *y); void sort(int n, (*compare)(char *,char *)); ... switch(expression) { case 'S': sort(nlines, stringCompare); break; case 'N': sort(nlines, numericCompare); break; case 'D': sort(nlines, dateCompare); break; } ... } void sort(int n, int (*compare)(char *, char *)) { ... } int stringCompare(char *s1, char *s2) { ... } int numericCompare(char *s1, char *s2) { ... } int dateCompare(char *s1, char *s2) { ... }
Here is a realistic example illustrating usage of pointers to pass a function as parameter to another function. This program is used for sorting an array of elements, where the array elements could be either all integers or all character strings. Now, depending upon the data type of the array elements a different helper function will have to be used to compare and sort elements. These helper functions are passed to the function sort() via its formal parameter compare. The latter then gets a handle to the passed function which it can invoke to do its task of sorting. This feature of C is quite helpful in creating polymorphic functions.
#include <stdio.h> #include <math.h> #define NLINES 100 main(int argc,char *argv[]) { char *linptr[NLINES]; int nlines; int str_cmp(char *x, char *y), num_cmp(char *s1, char *s2); void swap(char *px[], char *py[]); int readlines(char *lineptr[], int no_lines); void writelines(char *lineptr[], int no_lines); void sort(char *linptr[], int n, int (*compare)(char*, char*), void (*exch)(char *px[], char *py[])); int numeric = 0; if(argc > 1 && argv[1][0]=='-' && argv[1][1]=='n') numeric = 1; //If lines were read & memory allocated successfully, and also the number of lines //did not exceed maxlines i.e. NLINES (which is 100) if((nlines = readlines(linptr, NLINES)) > 0) { if(numeric) //call sort with function pointer compare pointing to num_cmp sort(linptr, nlines, num_cmp, swap); else //call sort with function pointer compare pointing to str_cmp sort(linptr, nlines, str_cmp, swap); writelines(linptr, nlines); } else printf("Error!! Input too big to sort.\n"); } #define MAXLEN 1000 //This function will keep reading line by line int readlines(char *lineptr[], int maxlines) { int getline(char *ln); int len, nlines; char *p, line [MAXLEN]; nlines = 0; //Loop will be exited when length of line is 0, //i.e. when [enter] key is pressed twice while((len = getline(line)) > 0) { if(nlines >= maxlines) //if nlines exceeds 100 lines return(-1); else if((p = (char *) malloc (len+1)) == NULL) //if memory allocation fails return(-1); else { strcpy(p, line); lineptr[nlines++] = p; } } return(nlines); //return the no. of lines read } //reads a line of text into array line, and returns its length int getline(char *ln) { int l = 0; while((ln[l] = getchar()) != '\n') l++; ln[l] = '\0'; return(l); } //numeric comparison function int num_cmp (char *s1, char *s2) { double r1,r2; r1 = atof(s1); r2 = atof(s2); if(r1 < r2) return(-1); if(r1 > r2) return(1); else return(0); } //string comparison function int str_cmp(char *x, char *y) { for(; *x == *y; x++, y++) if(*x == '\0') return(0); return(*x -*y); } void swap(char *px[],char *py[]) { char *temp; temp = *px; *px = *py ; *py = temp; } void writelines(char *lineptr[], int nlines) { while(--nlines >=0) // => for(i=0; i<nlines; i++) printf("%s\n", *lineptr++); } //Sorting routine with function pointers compare and exch void sort(char *v[], int n, int (*compare)(char *, char *), void (*exch)(char *px[], char *py[])) { int i, j, not_sorted = 1; j = n; while(not_sorted) { not_sorted = 0; for(i=0; i < (j-1); ++i) { if((*compare)(v[i], v[i+1]) > 0) { (*exch)(&v[i], &v[i+1]); not_sorted=1; } } j--; } return; }
What will be printed by the following program?
#include <stdio.h> main(int argc, char *argv[]) { printf("%s\n", *argv); }
How would you interpret the following declaration?
a) float *px; b) int (*p)[10]; c) char *p[15]; d) double (*p)(void); e) int (*p)(char *a, int *b); f) char (*(*x[4])())[5]; g) int *(*p)(char *a[]); h) int *(*p)(char (*a)[]); i) float (*f)(int *p); j) int (*f(int *p))[10]; k) double *g(int (*p)[]); l) long int (*f)(int (*p)[]); m) char *(*p[10])(char *c);
How to move your Email accounts from one hosting provider to another without losing any mails?
How to resolve the issue of receiving same email message multiple times when using Outlook?
Self Referential Data Structure in C - create a singly linked list
Mosquito Demystified - interesting facts about mosquitoes
Elements of the C Language - Identifiers, Keywords, Data types and Data objects
How to pass Structure as a parameter to a function in C?
Rajeev Kumar is the primary author of How2Lab. He is a B.Tech. from IIT Kanpur with several years of experience in IT education and Software development. He has taught a wide spectrum of people including fresh young talents, students of premier engineering colleges & management institutes, and IT professionals.
Rajeev has founded Computer Solutions & Web Services Worldwide. He has hands-on experience of building variety of websites and business applications, that include - SaaS based erp & e-commerce systems, and cloud deployed operations management software for health-care, manufacturing and other industries.