简体   繁体   中英

Parameters of passed function-pointer

I was supposed to write C implementation of C++ STL container map (associative array) by hashtable (array of pointers to linked lists of data) and some supporting functions, ie inserting element, deleting table... I've successfully written all of these, except for one, which is foreach(table, function_ptr) function, which calls the passed function for all data in the table (printing contents...).

I'm a little stuck here because I can't figure out what parameters should be passed to function_ptr , so it would be universal. As for now, I don't think it's possible.

If I would like just to pass a pointer for example to printf, it would be easy, prototype of foreach would look like this

foreach(table_t *t, int (*function_ptr)(const char *fmt, ...))

and I would just call it for every data node like this

function_ptr("%s, %d\n", node.key, node.data)

but if I use this and change my mind someday that I would like to pass my own function, I would have to change the code of caller-function and the foreach function as well.

Is there any easy way to do something like this?

The conventional way to specify "any argument type" is by using a void * like this:

foreach(table_t *t, int (*function_ptr)(void *p))

Then you can pass the address of each argument (which may be a complex data type, like a structure), and the function can cast it back to the appropriate type:

struct {
  int x;
  int y;
} numbers;

// Sums the numbers in a structure
int sum(void *p) {
  numbers *n = (numbers *) p;  // Cast back to the correct type
  return n->x + n->y;
}

// Counts the number of 'a' chars in a string
int numberOfA(void *p) {
  char *s = (char *) p;
  int num = 0;
  while (s != NULL && *s != '\0') {
    if (*s == 'a') {
      ++num;
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM