English 中文(简体)
What are function pointers used for, and how would I use them?
原标题:

I understand I can use pointers for functions.

Can someone explain why one would use them, and how? Short example code would be very helpful to me.

最佳回答

A simple case is like this: You have an array of operations (functions) according to your business logic. You have a hashing function that reduces an input problem to one of the business logic functions. A clean code would have an array of function pointers, and your program will deduce an index to that array from the input and call it.

Here is a sample code:

typedef void (*fn)(void) FNTYPE;
FNTYPE fn_arr[5];

fn_arr[0] = fun1; // fun1 is previously defined
fn_arr[1] = fun2;
...

void callMyFun(string inp) {
    int idx = decideWhichFun(inp); // returns an int between 0 and 4
    fn_arr[idx]();
}

But of course, callbacks are the most common usage. Sample code below:

void doLengthyOperation(string inp, void (*callback)(string status)) {
  // do the lengthy task
  callback("finished");
}

void fnAfterLengthyTask(string status) {
    cout << status << endl;
}

int main() {
    doLengthyOperation(someinput, fnAfterLengthyTask);
}
问题回答

One quite common use case is a callback function. For example if you load something from a DB you can implement your loading function so that it reports the progress to a callback function. This can be done with function pointers.

Callbacks. I make an asynchronous call to a chunk of code and want it to let me know when it finishes, I can send it a function pointer to call once it s done.

I m surprised no one mentioned "state machines". Function pointers are a very common way to implement state machines for tasks such as parsing. See for example: link.

You use a function pointer when you need to give a callback method. One of the classic example is to register signal handlers - which function will be called when your program gets SIGTERM (Ctrl-C)

Here is another example:

// The four arithmetic operations ... one of these functions is selected
// at runtime with a switch or a function pointer
float Plus    (float a, float b) { return a+b; }
float Minus   (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide  (float a, float b) { return a/b; }

// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
   float result;

   // execute operation
   switch(opCode)
   {
      case  +  : result = Plus     (a, b); break;
      case  -  : result = Minus    (a, b); break;
      case  *  : result = Multiply (a, b); break;
      case  /  : result = Divide   (a, b); break;
   }

   cout << "Switch: 2+5=" << result << endl;         // display result
}  

// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
   float result = pt2Func(a, b);    // call using function pointer

   cout << "Switch replaced by function pointer: 2-5=";  // display result
   cout << result << endl;
}

You can learn more about function pointers here http://www.newty.de/fpt/index.html

If you are more familiar with object-oriented languages, you can think of it as C s way to implement the strategy design pattern.

Let s do a map-like function for C.

void apply(int *arr, size_t len, int (*func)(int))
{
    for(size_t i = 0; i < len; i++)
        arr[i] = func(arr[i]);
}

That way, we can transform a function that works on integers to work on arrays of integers. We could also do a similar version:

void apply_enumerated(int *arr, size_t len, int (*func)(size_t, int))
{
    for(size_t i = 0; i < len; i++)
        arr[i] = func(i, arr[i]);
}

This does the same thing, but allows our function to know which element it s on. We could use this, for example:

int cube(int i) { return i * i * i }

void print_array(int *array, size_t len, char *sep)
{
    if(sep == NULL) sep = ", ";
    printf("%d", *array);
    for(size_t i = 1; i < len; i++) printf("%s%d", sep, array[i])
}

#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))

int main(void)
{
    int array[5] = { 1, 2, 3, 4, 5 };
    print_array(array, ARRAY_SIZE(array), NULL);
    apply(array, ARRAY_SIZE(array), cube);
    print_array(array, ARRAY_SIZE(array), NULL);
    return 0;
}

That code will print:

1, 2, 3, 4, 5
1, 8, 27, 64, 125

For our enumeration example:

int mult(size_t i, int j) { return i * j }

// print_array and ARRAY_SIZE as before

int main(void)
{
    int array[5] = { 1, 2, 3, 4, 5 };
    print_array(array, ARRAY_SIZE(array), NULL);
    apply_enumerated(array, ARRAY_SIZE(array), mult);
    print_array(array, ARRAY_SIZE(array), NULL);
    return 0;
}

This prints:

1, 2, 3, 4, 5
0, 2, 6, 12, 20

As a more real world example, a string library could have a function that applies a function that operates on single characters to all the characters in the string. An example of such functions are the standard-library toupper() and tolower() functions in ctype.h - we could use this string_apply() function to make a string_toupper() function easily.

A very good and easy to understand tutorial: http://www.newty.de/fpt/index.html

Hope this helps.

Another usage for pointers is iterating lists or arrays.

For code, check out qrdl s response to state machines tutorials.

I ve used a variant of his method to implement a a menu for an LCD display I have on a board. Very very useful, makes the coding much cleaner and easier to read. Using function pointers makes expanding the number, names and ordering of menus very easy, and hides all those details from the higher level calling function that just sees hey, I write to the LCD here.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签