How2Lab Logo
tech guide & how tos..


Pointers in C - Part 9 of 9


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;
}


Exercises

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);

Share:
Buy Domain & Hosting from a trusted company
Web Services Worldwide | Hostinger
About the Author
Rajeev Kumar
CEO, Computer Solutions
Jamshedpur, India

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.


Refer a friendSitemapDisclaimerPrivacy
Copyright © How2Lab.com. All rights reserved.