'passing a function vs calling a function

what is the difference if any of calling a function vs passing a function in c?

For instance on printf there is:

_doprnt(register const char *fmt, va_list *argp, void (*putc)(char), int radix){
...
while ((c = *fmt) != '\0') {
    if (c != '%') {
        (*putc)(c);
        fmt++;
        continue;
    }

Why do that if you can simply call it?



Solution 1:[1]

You can pass a function usually referred to as a callback for to be called in the case some event occurs. Calling a function occurs..well when you call it. In your example it seems like it's taking into account some arguments before calling putc. Regardless it's probably not the best example.

Imagine a keyboard handler which triggers a callback each time a user presses a key. You might be able to register the handle like so:

void registerkeyboardhandler(keyboardcallback handler){
    /*
     *create a handler
     */
}

Which wants a function pointer of type keyboardcallback handler, and we can define that as such:

typedef void (*keyboardcallback)(int keycode, int down);

Now registerkeyboardhandler will probably hook onto some keyboard input and whenever a user presses a key, the callback will be called and a keycode as well as if the key was down/up will be passed.

The handler could be simple

void keyboardcallbackhandler(int keycode, int down){
    switch(keycode){
        case 0x00:
            //do something
            switch(down){
                case 0:
                    break;
                case 1:
                    break;
            }
            break;
    }
}

And we can probably call registerkeyboardhandler from main

int main(void){
    registerkeyboardhandler(keyboardcallbackhandler);
}

But essentially, function pointers are ideal for callbacks to be triggered in the case of some event to occur potentially later on.

A more practical example could be an array sorting method which allows you to dictate how you want the sorting to occur.

Consider this sort method

void sort(int* p,int size, sortmethod smt){
    for(int i = 0; i < size; ++i){
        for(int j = 0; j < size; ++j){
            if(smt(p[i],p[j])){
                int temp = p[i];
                p[i] = p[j];
                p[j] = temp;
            }
        }
    }
}

It takes an int array, a size as well as a callback to decide how you wish to perform the sort between two integers. And this is my array

int p[] = {3,2,4,1,5,9};

Now if I wanted to sort from least to greatest I could make my sort callback method like so

int sortby(int x, int y){
    return x<y;
}

But if I wanted to make my array from greatest to least I could just flip the sign

int sortby(int x, int y){
    return x>y;
}

And when I call sort from main, I can use my callback to let sort know how I want the sort to be performed

typedef int (*sortmethod)(int x, int y);
int sortby(int x, int y){
    return x>y;
}

void sort(int* p,int size, sortmethod smt){
    for(int i = 0; i < size; ++i){
        for(int j = 0; j < size; ++j){
            if(smt(p[i],p[j])){
                int temp = p[i];
                p[i] = p[j];
                p[j] = temp;
            }
        }
    }
}

int main(void){
    int p[] = {3,2,4,1,5,9};
    sort(p,sizeof(p)/sizeof(int),sortby);
    for(int i = 0; i < sizeof(p)/sizeof(int);++i){
        printf("%d\n",p[i]);
    }
}

The sort takes care of the algorithm while the critical step of how the sorting should be done is handled by you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1