In C Why function pointers are better suited in function call backs? - c

I know function call back is embedding another function pointer in the call of another function like this:
Function Declaration:
function_call_back(int x, int y, void (*functonPtr)(int x, char y , struct newStruct* sptr))
void func(int x , char y , struct newStruct* sptr1)
{
//perform Algorithm 1 on x,y ,sptr1
}
void func2(int x , char y , struct newStruct* sptr2)
{
//perform Algorithm 1 on x,y ,sptr2
}
void func3(int x , char y , struct newStruct* sptr3)
{
//perform Algorithm 1 on x,y ,sptr3
}
void func4(int x , char y , struct newStruct* sptr4)
{
//perform Algorithm 1 on x,y ,sptr4
}
main()
{
// function calling
function_call_back(23, 2256, func1);
}
Here the third argument is func, as function name is equivalent to function pointer
I agree that the func here can be altered with different variation of similar function signature by adding this line in main above before call to function_call_back:
typedef void (*fptr)(int int x , char y , struct newStruct* ptr);
fptr f1 = func2; // or func3, or func4
function_call_back(23, 2256, f1);
The third argument is func, as function name is but I was wondering this can be achieved in the below way also, by simply adding the function-calling code in the call to function_call_back:
function_call_back(23, 2256, functionCallingcode); //third argument is func
The new declaration of function_call_back is:
function_call_back(int x, int y, int functionCallingCode)
And its new definition is:
void function_call_back(int x, int y, int functionCallingCode)
{
switch(functionCallingCode)
case 1:
func1(1,"g",sptr1);
break;
case 2:
func2(1,"c",sptr2);
break
case 3:
func3(1,"d",sptr3);
break;
case 4 :
func4(1,"s",sptr4);
break ;
default :
printf("Wrong Function calling code");
}
}
Then why to use function pointer?

With the switch statement, you can call every function that you choose to code into your callback function. You are guaranteed that only one of your known collection of functions can be called.
With the function pointer, you can call any function that you may define at a later and completely unrelated point in your development. You're free to define and use any callback function with a matching signature.
In other words, the switch allows you to branch among a bounded set of choices, while the function pointer gives you unbounded flexibility. Usually there's little reason to prefer anything else over the function pointer.

They are not better, they are practically the only option you have.
You can do this switch, but in the same approach, you can just write the whole program in one functions. Functions are there to separate code units, and this "switch-function" just units too many things.

In the case you describe you clearly can get the functionality you want without using a function pointer.
However consider what happens if you want to add the option of func5 in a few weeks time. And then as time goes by you want to add func6, func7, ..., func10, func20. function_call_back() gets bigger and messier whereas with the function pointer version you can add as many different funcs as you want without having to edit function_call_back() at all.
The function pointer implementation also gives you the flexibility to parcel function_call_back() up as part of a library that you or anyone else can use in another program without having to mess with, or even have, the source code. See the standard library qsort function for an example of why this is really handy.

Related

How can I solve this simple C function?

I am taking a hybrid class of "Algorithms, architecture, and assembly language" at my local community college. Although it's an intro class and mainly focuses on how computers turn code into binary, we have some assignments for C code. Some of the stuff we've never even gone over in class, and I'm lost.
The instructions read:
Write a function named DoSomething, with no return value, it should do just one (1) thing: multiply the global variable my_result by 5 and store the result back into my_result
You do not have to call DoSomething, or initialize my_result, I will do that.
I have tried
int my_result;
dosomething (my_result) {
my_result = my_result * 5;
}
but this is incorrect. I have almost zero experience with C language and am stuck. I'm not asking anyone to do my homework, I just want to understand. This has not been covered in class.
You almost have it. Since my_result is global, you do not need to pass it into the function, it is accessible everywhere. Oh, and every function needs its return value specified. Use void to specify that there is no return value and no parameters.
int my_result;
void dosomething (void) {
my_result = my_result * 5;
}
A correct function declaration must have a type, the name of the function and its arguments.
type function_name(type1 arg1, type2 arg2, type3 arg3, ...);
If a function does not return anything, then type must be void
void function_name(type1 arg1, type2 arg2, type3 arg3, ...);
If a function does not take any parameter, then the you can use void instead
of the list of arguements:
type function_name(void);
Your dosomething function is missing the return type, which should be void
(assignment says Write a function named DoSomething, with no return value)
and it takes no arguments (at least the assignment does not specify any), so the
correct prototype of the function must be:
void DoSomething(void);
So the correct program
#include <stdio.h>
int my_result;
void DoSomething(void)
{
my_result = my_result * 5;
}
int main(void)
{
my_result = 6; // initializing global variable
DoSomething();
printf("my_result: %d\n", my_result);
return 0;
}
which will print my_result: 30.
There is nothing to get worried about. Relax, it's just part of the process in becoming a good developer.
To solve such problems, first note what the function expects and we want from the function to return.
Now, in your question, it is given that function would return nothing. So the return type of the function would be void.
Now, since we have to use a global variable, it means function expects no argument.
Hence, our code is :
#include <stdio.h>
int my_result; // Our Global Variable
void doSomething (void) // Our Function
{
my_result = my_result * 5;
}
int main()
{
/* Asking the value of my_result */
printf("Please enter a value : ");
scanf("%d", my_result);
doSomething();
printf("\nNew value of my_result is : %d\n", my_result);
return 0;
}
// End of main.
The instructions read:
Write a function named DoSomething, with no return value,…
So code for that is:
void DoSomething(void)
… it should do just one (1) thing: Multiply the global variable my_result by 5 and store the result back into my_result.
And code for that is:
{
my_result = my_result * 5;
}
You do not have to call DoSomething, or initialize my_result, I will do that.
Done. The total code requested is:
void DoSomething(void)
{
my_result = my_result * 5;
}
You have indicated in your comments that you are submitting this code into some sort of automatic grading/checking software. So that software is designed to accept code that matches the assignment, no more and no less. Quite likely, it puts your code into a file and that compiles a source file that includes the former file with #include. That source file defines my_result and main, so your code should not, or it will cause compilation and/or link errors. You need to submit just the code requested in the instructions.
Notes about your code:
The instructions say to write a routine named DoSomething. You used dosomething. These are different in C; the case matters.
You declared the routine without specifying a return type. The instructions say the instruction has no return value, but that does not mean you should just omit any return type. You should explicitly say there is no return value by using void for the return type of the function, as in void DoSomething(…). (For historic reasons, if you omit the return type in a function declaration, it defaults to int. Letting the type default like that is old syntax and should be avoided.)
The instructions did not say whether the routine should take parameters. This is a shortcoming in the instructions. However, dosomething (my_result) is incorrect for two reasons. One, my_result is described as a global variable, not a parameter. Two, it is the wrong syntax for a parameter declaration. A parameter declaration must have a type, as in dosomething(int x). Since the routine needs no parameters, a proper declaration is void DoSomething(void). (Although there is some possibility the instructor intended void DoSomething(), but that would not generally be preferred.)

Function pointer with some parameters set

How can I create a function pointer to a function where some parameters are set to be fixed upon the definition.
Here is an example what I mean:
Let's say I have the function
int add (int n, int m) {
return n+m;
}
and the function pointer type
typedef int (*increaser)(int);
What I want is a pointer to the function add which fixes the first parameter to 1 and leaves the second paramenter open. Something along the lines of
increaser f = &add(1,x);
How can I accomplish this?
What I want is a pointer to the function add which fixes the first parameter to 1 and leaves the second paramenter open.
There is no such thing in C. The closest you can come is to create a wrapper function and make a pointer to that:
int add1(int x) {
return add(1, x);
}
increaser f = &add1;
If you don't need a pointer to the function then you can use a macro:
#define increaser(x) add(1, (x))
C does not support doing this directly. In C++ there is std::function and bind which can achieve this however.
None the less for a pure C solution the closest you can reasonably get is defining a new function that calls add like:
int increment(int input) {
return add(1, input);
}
Then you can do:
increaser f = &increment;

How to define an array of function pointers and the functions don't have same input argument definition?

Is it possible to define an array of function pointers (and the functions don't have se same input argument ) as indicating in the following code ?
If yes what I have to put in the function definition int (*handler)(/*what Ihave to put here ?*/);
struct handler_index {
const char *name;
int (*handler)(/*what Ihave to put here ?*/);
};
int handler0 (int a, int b)
{
printf("%d\n",a+b);
}
int handler1 (int a, int b, int c)
{
printf("%d\n",a+b+c);
}
int handler2 (int a, int b, int c, int d)
{
printf("%d\n",a+b+c+d);
}
const struct handler_index handler_index[] = {
[0] = {"handler0", handler0},
[1] = {"handler1", handler1},
[2] = {"handler2", handler3},
};
Just put nothing:
int (*handler)();
it means the function has an unspecified (but non-variable) number and types of parameters.
Any function that returns an int and with a fixed variable number of parameters can be assigned to handler.
Whilst int (*handler)() will indeed allow variable number of arguments for th function, I fail to see any benefit in this. Function pointers are useful when you have a piece of code that takes something, finds the "right thing to do" (e.g comparing the "name" with some input from elsewhere), and calls the function pointer to do whatever it has to do. The function pointer calling code needs to know how many arguments the function has (how else would it pass the right number and order of arguments.
I don't actually see any meaningful use of this at all. Yes, you can pass a variable number of arguments to a function, but the code HAS to know what arguments the function takes.
Unless the arguments are somehow specified in the definition of the struct - but then you need to define different content for the struct to allow for that.
I would suggest that you need to think about what you are trying to achieve, and then come up with a solution to the problem, most likely using a different method.
Put nothing. Just empty brackets.
int (*handler)();

Function pointers, design

I am in a problem with a design question in C.
Let's say that I have a pretty large amount of functions, with different argument count.
POQ:
int print_one(int x)
{
printf("one: %d\n", x);
return 1;
}
int print_three(int x, int y, int z)
{
printf("three: %d-%d-%d\n", x, y, z);
return 3;
}
Now, I want to connect some properties to these functions in a structure, so that I can manipulate them without knowing the exact function, including their parameter count (I might even call the structure interface)
I tryd it like this, (& I think is pretty wrong):
typedef int (*pfunc)(int c, ...);
typedef struct _stroffunc
{
pfunc myfunction;
int flags;
int some_thing_count;
int arguments[10];
int argumentcount;
} stroffunc;
int main()
{
stroffunc firststruct;
firststruct.pfunc = (pfunc) print_two;
firststruct.something_count = 101;
arguments[0] = 102;
argumentcount = 1;
flag &= SOME_SEXY_FLAG;
// now I can call it, in a pretty ugly way ... however I want (with patially random results ofc)
firststruct.pfunc(firststruct.arguments[0]);
firststruct.pfunc(firststruct.arguments[0], 124, 11);
firststruct.pfunc(1, firststruct.arguments[0], 124, 1, 1);
}
I find this solution very ugly, & I think (hope) that there is a better solution for calling & and setting the function pointers.
I'm just hoping, that I was clear enough ...
NOTE: I didn't compile this code, but i compiled & run a very similar one so the concepts are working.
NOTE: pure C needed
Calling a non-variadic function through a variadic function pointer leads to undefined behaviour. For a start, recall that the arguments to variadic functions undergo the default argument promotions (chars are converted to ints, etc.), which will totally screw things up.
It's not clear how or why you intend to dynamically call a function with differing numbers of arguments. But one solution could be to use a union:
typedef struct {
int num_args;
union {
void (*f1)(int);
void (*f2)(int, int);
void (*f3)(int, int, int);
} func;
} magic;
...
magic m;
...
switch (m.num_args) {
case 1: m.func.f1(arg1); break;
case 2: m.func.f2(arg1, arg2); break;
case 3: m.func.f3(arg1, arg2, arg3); break;
default: assert(0);
}
A second solution would be to rewrite all of your functions as variadic.
This is on the edge of my knowledge, but I believe that you need to make the functions variadic as well, due to incompatibilities in the ABI.
see: wikipedia's example
Maybe you can add a library which have some functions to handle the struct, like a "pseudo" class,
int initFunc(int (*pfunc)(int c,...));
This function will save the pointer into the struct, like a context in POO, in the struct you will use it like a "map" of all the function an you will call each one using an id.
which returns an id, and you save it in an array,
then another func say
int call(int id,int p1,...);
where you say the function id and the parameters, sure you must now which function is each id

Trying to understand function pointers in C

I am trying to understand function pointers and am stuggling. I have seen the sorting example in K&R and a few other similar examples. My main problem is with what the computer is actually doing. I created a very simple program to try to see the basics. Please see the following:
#include <stdio.h>
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23,(int(*)(void*,void*))(i==1?func0:func1));//34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, int(*somefunc)(void *, void *)){
int *xx =&x;
int *yy=&y;
printf("%i",somefunc(xx,yy));
}
int func0(int *x, int *y){
return (*x)*(*y);
}
int func1(int *x, int *y){
return *x+*y;
}
The program either multiplies or adds two numbers depending on some variable (i in the main function - should probably be an argument in the main). fun0 multiplies two ints and func1 adds them.
I know that this example is simple but how is passing a function pointer preferrable to putting a conditional inside the function myfunc?
i.e. in myfunc have the following:
if(i == 1)printf("%i",func0(xx,yy));
else printf("%i",func1(xx,yy));
If I did this the result would be the same but without the use of function pointers.
Your understanding of how function pointers work is just fine. What you're not seeing is how a software system will benefit from using function pointers. They become important when working with components that are not aware of the others.
qsort() is a good example. qsort will let you sort any array and is not actually aware of what makes up the array. So if you have an array of structs, or more likely pointers to structs, you would have to provide a function that could compare the structs.
struct foo {
char * name;
int magnitude;
int something;
};
int cmp_foo(const void *_p1, const void *_p2)
{
p1 = (struct foo*)_p1;
p2 = (struct foo*)_p2;
return p1->magnitude - p2->magnitude;
}
struct foo ** foos;
// init 10 foo structures...
qsort(foos, 10, sizeof(foo *), cmp_foo);
Then the foos array will be sorted based on the magnitude field.
As you can see, this allows you to use qsort for any type -- you only have to provide the comparison function.
Another common usage of function pointers are callbacks, for example in GUI programming. If you want a function to be called when a button is clicked, you would provide a function pointer to the GUI library when setting up the button.
how is passing a function pointer preferrable to putting a conditional inside the function myfunc
Sometimes it is impossible to put a condition there: for example, if you are writing a sorting algorithm, and you do not know what you are sorting ahead of time, you simply cannot put a conditional; function pointer lets you "plug in" a piece of computation into the main algorithm without jumping through hoops.
As far as how the mechanism works, the idea is simple: all your compiled code is located in the program memory, and the CPU executes it starting at a certain address. There are instructions to make CPU jump between addresses, remember the current address and jump, recall the address of a prior jump and go back to it, and so on. When you call a function, one of the things the CPU needs to know is its address in the program memory. The name of the function represents that address. You can supply that address directly, or you can assign it to a pointer for indirect access. This is similar to accessing values through a pointer, except in this case you access the code indirectly, instead of accessing the data.
First of all, you can never typecast a function pointer into a function pointer of a different type. That is undefined behavior in C (C11 6.5.2.2).
A very important advise when dealing with function pointers is to always use typedefs.
So, your code could/should be rewritten as:
typedef int (*func_t)(int*, int*);
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23, (i==1?func0:func1)); //34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, func_t func){
To answer the question, you want to use function pointers as parameters when you don't know the nature of the function. This is common when writing generic algorithms.
Take the standard C function bsearch() as an example:
void *bsearch (const void *key,
const void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *));
);
This is a generic binary search algorithm, searching through any form of one-dimensional arrray, containing unknown types of data, such as user-defined types. Here, the "compar" function is comparing two objects of unknown nature for equality, returning a number to indicate this.
"The function shall return an integer less than, equal to, or greater than zero if the key object is considered, respectively, to be less than, to match, or to be greater than the array element."
The function is written by the caller, who knows the nature of the data. In computer science, this is called a "function object" or sometimes "functor". It is commonly encountered in object-oriented design.
An example (pseudo code):
typedef struct // some user-defined type
{
int* ptr;
int x;
int y;
} Something_t;
int compare_Something_t (const void* p1, const void* p2)
{
const Something_t* s1 = (const Something_t*)p1;
const Something_t* s2 = (const Something_t*)p2;
return s1->y - s2->y; // some user-defined comparison relevant to the object
}
...
Something_t search_key = { ... };
Something_t array[] = { ... };
Something_t* result;
result = bsearch(&search_key,
array,
sizeof(array) / sizeof(Something_t), // number of objects
sizeof(Something_t), // size of one object
compare_Something_t // function object
);

Resources