C. Keith Ray

C. Keith Ray is developing software for Sizeography and Upstart Technology. He writes code for multiple platforms and languages, including iOS® and Macintosh®.
Go to Sizeography and Upstart Technology to join our mailing lists and see more about our products. Keith's Résumé (pdf)

Friday, July 18, 2014

Function Pointer Syntax Cheat-Sheet-By-Example

#include <stdio.h>

// Using * to indicate the parameter is a pointer to a function.

void functionTakingFunctionPointerOldStyle(int (*pf)(int))
{
    printf("\nold style pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = (*pf)(12); // Using * to deref function pointer.
        printf("pf(12) = %d\n", x);
    }
}

// We don't need * to indicate that a parameter is a function pointer.

void functionTakingFunctionPointerNewStyle(int pf(int))
{
    printf("\nnew style pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = pf(12); // Don't need * to deref function pointer, either.
        printf("pf(12) = %d\n", x);
    }
}

// Blocks. Like old-style function pointer, using ^ instead of *.

void functionTakingBlock(int (^pf)(int)) // like old-style function pointer.
{
    printf("\nblock pf = %p\n", pf);
    if (pf != NULL)
    {
        int x = pf(12); // Same syntax as calling function or function-pointer.
        printf("pf(12) = %d\n", x);
    }
}

/*

If we use a typedef, then the syntax for parameter declaration is simple:

     typedef int (*funcPtr)(int);

     void functionTakingFunctionPointer(funcPtr fp);

 But now we need to remember how to declare the function-pointer typedef!

 This is how I create a typedef for a function pointer type:

 1. Start with the function declaration itself.

     int functionTakingIntReturningInt(int i);

 2. Remove parameter names.

     int functionTakingIntReturningInt(int);

 3. Change the function name to a name appropriate for this function-pointer type, maybe suffixed with "FuncPtr" if you can't think of something more meaningful. Don't suffix "Type" to the name—like "FuncPtrType"—it makes you look like a newby. (I stopped doing that last week.)

     int funcPtr(int);

 4. Wrap name with (* and )

     int (*funcPtr)(int);

 5. Add typedef

     typedef int (*funcPtr)(int);

 6. Profit!

*/

int functionTakingIntReturningInt(int i)
{
    return i + 1;
}

int main(int argc, char *argv[]) 
{
    // "old" style C code - using "&" take address of the function.
    functionTakingFunctionPointerOldStyle( NULL );
    functionTakingFunctionPointerOldStyle( & FuncionTakingIntReturningInt );

    // "new" style C code - don't need "&" for function type.
    functionTakingFunctionPointerNewStyle( NULL );
    functionTakingFunctionPointerNewStyle( FuncionTakingIntReturningInt );

    // blocks
    functionTakingBlock( NULL );
    functionTakingBlock( ^(int i){ return i + 1; } );
}


Output:


old style pf = 0x0

old style pf = 0x1004aa980
pf(12) = 13

new style pf = 0x0

new style pf = 0x1004aa980
pf(12) = 13

block pf = 0x0

block pf = 0x1004ab0f0
pf(12) = 13