2

Possible Duplicate:
What is the point of function pointers?

can anyone explain what function pointers are and why they are needed in layman terms. In c context please?

Community
  • 1
  • 1
begsor12
  • 21
  • 1
  • 5
    I would recommend that you consult your C book; if you do not have one, I would recommend getting one of the introductory books listed in [The Definitive C Book Guide and List](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). – James McNellis Jul 16 '10 at 20:02
  • 2
    dup: http://stackoverflow.com/questions/3229349/function-pointer/3229465#3229465 – eruciform Jul 16 '10 at 20:04
  • 2
    @eruciform That's a bit lame, linking directly to your own answer in a question that was itself closed as a duplicate – Tyler McHenry Jul 16 '10 at 20:07
  • @tyler: new here - didn't know that's taboo. and i didn't even see that the other one was closed, i just remembered it from a few days ago and posted it. real dup: http://stackoverflow.com/questions/2592137/what-is-the-point-of-function-pointers – eruciform Jul 16 '10 at 20:15
  • @eruciform: In reply to your comment to your now-deleted answer: it's no problem, and welcome to Stack Overflow :-) – James McNellis Jul 16 '10 at 20:28
  • Is this really an exact duplicate? The other question is C++, and most of the answers give examples of functors. Other answers addressed what the function pointers are used for, but don't necessarily address what they are. – Cogwheel Jul 16 '10 at 20:32
  • @james: just out of curiosity, do things marked as exact duplicates have their answers ported over to the duplicate? so that people that work to make a useful answer on a question that gets closed get to have their answer seen on the "top level non-dup" question? is it improper to port an answer over if this is not the case? – eruciform Jul 16 '10 at 20:42
  • @eruciform: Duplicate questions are not merged automatically: often duplicate questions have different phrasing and key words that help to make finding things via a Google search much easier (you might search for something and match the duplicate, then get linked to the main question). I don't actually know what the etiquette is for copying an answer to the question that is still open, but you could delete an answer from the closed question and repost it as an answer to the still open one. You can also flag the question (click the flag link) and just ask a moderator to merge the questions. – James McNellis Jul 16 '10 at 20:47
  • @Cogwheel: That question is tagged both [c] and [c++] and it asks essentially the same thing; some of the information is relevant to both C and C++, and the information that is C++-specific is pretty obvious. It might be nice to have a more detailed C-specific answer in reply to it. – James McNellis Jul 16 '10 at 20:51
  • 1
    The "duplicate" question is "what use are function pointers"; this si "what are function pointers", which goes to implementation, not intent of using. so I vote to re-open. – tpdi Jul 16 '10 at 20:53
  • @James: point taken re: c vs. c++ (I often assume it's just the common "C/C++" confusion that leads people to use both tags). It still feels like the other question only represents half of this one, though. – Cogwheel Jul 16 '10 at 20:59
  • @tpdi: in fairness, this question does address both aspects, to some extent. – Cogwheel Jul 16 '10 at 21:05

4 Answers4

2

Under the hood, a function is just a location in the binary machine code of your program. When you use functions in C, the compiler produces instructions that jump to that particular location after passing in the function's arguments.

A function pointer is a variable you can use to hold the location of a function. This allows one part of your code to determine what function is used in another part of your code. For example, the qsort function takes a function pointer that you use to determine the order of the objects being sorted.

Cogwheel
  • 22,781
  • 4
  • 49
  • 67
  • so you dont know which fuction to call in runtime and you do some type of comparison and call the appropriate function. am I right? – begsor12 Jul 16 '10 at 20:23
  • I think you have the gist of it. For example, with qsort, you could choose either ascending or descending order based on user input. – Cogwheel Jul 16 '10 at 20:28
1

Pointers are the addresses of memory.

A function pointer the address in memory where the code for a function starts.

Often, you know at compile time what function you want to call, so you refer to it by name. When the code si compiled, teh compiler replaces that name with the (usually relative) address of the actual machine code.

But sometimes you don't know what function you want to call at compile time. You could use a switch or something to call different functions:

switch(c) {
  case '+' : add( op1, op2); break;
  case '*' : multiple( op1, op2); break;
  case '/'  : divide(op1, op2); break;
}

but this is tedious and error-prone.

Or you may be writing a library function, like qsort, that knows how to sort any type, but that requires a comparator function to do the sorting. So that we don't have to open up and recompile qsort, qsort allows us to pass it the of the code -- that is, the function -- that we want it to use to compare our user-defined type.

So C (and C++) allow the address of that code -- the address of the function -- to be taken. Taking the address yields a value of type pointer to function (actually, of type pointer to function of type, where the type of the function's signature -- that is, the type and number of its parameters -- and its return type, the type of object it returns. (Note that the signature doesn't include the return type, but the type of the function includes both signature and return type.)

Anyway, this yielded value can of course be assigned to a variable of compatible type -- a pointer to a function, and passed around or copied like any other variable, as after all it's just a number, an address in memory.

So given that we have a function foo, with return type int and signature const void*, const void*:

 int foo( const void* lhs, const void* rhs);

we can create a variable of that type:

 int ( *foopointer) ( const void*, const void* ) ;

Yes, really, that's a variable declaration! Read that as "foopointer is a pointer to a function taking two const void pointers and returning int", by reading the name ("foopointer") then left to the pointer ("*"), then right to the parens ("const void*, const void*)", then back left to the int that it returns. The first set of parens are necessary to prevent this from declare a function that returns a pointer-to-int.

Then we can assign the address of our function foo to our variable foopointer, using the address-of operator ("&"):

  foopointer = &foo;

Actually the address-of operator isn't strictly neccessary, and is implied if we don't use it, but use it to make it clear that you're taking an address. It helps readers.

Then we can use foopointer, say to call qsort:

  int some_array_of_int[] = { 1, 3, 2 ) ;
  qsort( some_array_of_int, 
        3 /* elements */, 
        sizeof(int) /*each element is how big?*/, 
        foopointer) ;

Of course, we could just use foo directly: qsort( some_array_of_int, 3 /* elements */, sizeof(int) /each element is how big?/, foo) ;

Either way, qsort will now use foo to compare the numbers in our array, in order to sort them. (A comparator function should return specific values to allow that to happen, which is beyond the scope of this discussion, but in general, *lhs - *rhs).

Now we haven't specified how foo sorts things, but we don't have to in order to reverse how it sorts, as to do that we can just return the negation of foo's return value :

 int reverse_foo( const void* lhs, const void* rhs) {
    return - foo( lhs, rhs ) ;
 }

Now we can decide at runtime whether to sort or list ascending or descending:

  bool reverse = get_reverse_from_user_or_somthing();

  qsort( some_array_of_int, 
         3 /* elements */, 
         sizeof(int) /*each element is how big?*/, 
         reverse ? reverse_foo : foo ) ;

Whoever wrote qsort had no idea how you'd write foo (and reverse_foo), and you had (possibly) no way to re-compile qsort to let it know about foo (or reverse_foo). But thanks to function pointers, qsort can call foo despite the two functions being written years apart, by different coders.

tpdi
  • 34,554
  • 11
  • 80
  • 120
0

A function pointer is just like any other pointer, except it points to a function (code).

There are many uses - for example, you could implement message handlers for a network protocol by using a table of structures, each containing a pointer to a handler function, and other associated data to identify each message. Then when a message is received, you can look up the appropriate function and call it via the table's pointer.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
  • so you dont know which fuction to call in runtime and you do some type of comparison and call the appropriate function. am I right? – begsor12 Jul 16 '10 at 20:15
0

Function pointers point to the binary section of code for a particular function.

The only time I've ever used them was with pthreads. When you launch a thread, you need to tell it where to begin executing, so you would give it a pointer to the function that it should start executing in. In essence, that function becomes the "main()" for the thread, and once it returns from that function, the thread dies.

Without function pointers, there's no way for you to tell pthreads where to begin execution for a new thread.

Phil
  • 1