In the code, I omitted parameters for int (*bar) and assigned &foo, which as 3 arguments, to bar. (*bar) received the numbers and gave me a return value. I thought this is ok but I've heard that this is actually UB. How does (*bar) receive the numbers? Thx
#include <stdio.h>
int foo(int a, int b, int c){
return a+b+c;
}
int main(void) {
int (*bar)() = &foo;
printf("%d", bar(1, 2, 3));
return 0;
}
edit
When I pass more than three arguments to bar() (say 5 arguments), the program works. Where do the two extra arguments go?
I have to following C code:
a.b[(c+d(e,f,g)**i)]->j<-k
Now I have to add code to make it compile.
Most of that isn't a problem but what really irritates me is the d(e,f,g)**i part. **i as I understand is a pointer to a pointer, but I don't know how to handle it directly after a function call.
Just break it down:
d(e,f,g)**i
FunctionCall d with params e,f,g
Multiplied by
pointer-dereferce of i
Or:
d (e,f,g) * (*i)
Func. Params Multiply value-stored-at-pointer
Simple Enough
d(e,f,g) * *i // where d(e,f,g) is a function which should return a value and
*i is a pointer value
Eg if function d(e,f,g) returns 10 and if *i=5 then then output will be 10*5 = 50
Well this is relatively awful. Let's work from the inside out and remove things as we deal with them:
d is a function with 3 parameters. Let's assume it can return an int, and if it can't we'll deal with that later:
int e, f, g;
int d(int, int, int);
d(e,f,g) * *i will be fine if i is a pointer to an int.
int *i;
c + d(e,f,g) * *i will be fine if c is also an int.
int c;
So now we have the inside of the brackets completed. We also wanted that to be an integer so that it could work as an array notation. So we're good there. Let's rewrite the question without some of the stuff that we've resolved.
a.b[<some integer>]->j < -k
We can do the right side pretty easily.
int k;
This part is difficult to put into words, but I'm just walking the types. b is a double star because it's using array brackets followed by an -> sign.
struct {
struct {
int j;
} **b;
} a;
So we end up with:
#include <stdlib.h>
int main() {
int e, f, g;
int d(int e, int f, int g);
int *i;
int c;
int k;
struct {
struct {
int j;
} **b;
} a;
a.b[(c+d(e,f,g)**i)]->j<-k;
}
When I try to compile the following line
int* x[](), (*y)();
I get the error "x declared as an array of functions of type int()"
You cannot really declare an array of functions, but you can have an array of function pointers, which will probably give you the same effect, because you can invoke them without explicit dereferencing.
The following will declare an array of 5 function pointers which return int*.
int* (*x[5])();
The website cdecl will let you play with various pointer declarations to see what they mean in English.
Here is the golden rule for reading C declarations, stolen from this old article.
Start at the variable name (or innermost construct if no identifier is
present. Look right without jumping over a right parenthesis; say what
you see. Look left again without jumping over a parenthesis; say what
you see. Jump out a level of parentheses if any. Look right; say what
you see. Look left; say what you see. Continue in this manner until
you say the variable type or return type.
When applied to the declaration above, we say:
x is an array of 5 pointers to functions returning pointer to int.
As SteveCox correctly commented below, we note that if we run into a type qualifier on the left hand side when following the above rule, it will describe the type to its left rather than its right. For example, the following declaration declares an array of 5 pointers to functions returning const pointer to int, not pointer to const int.
int* const (*x[5])();
Try this for an array of 2 function pointers.
#include <stdio.h>
int *first(void) { return NULL; }
int *second(void) { return NULL; }
int main(void) {
int *(*fx[2])(void);
fx[0] = first;
fx[1] = second;
/* ... */
if (fx[0]() == fx[1]()) {
printf("Calling both functions returns the same value.\n");
}
return 0;
}
A practical application might look like:
#include <ansi_c.h>
int add_(int, int);
int sub_(int, int);
int mul_(int, int);
int div_(int, int);
enum {
ADD,
SUB,
MUL,
DIV
};
int (*mathOps[4])(int, int);
int main(void)
{
int i;
mathOps[ADD]=add_;
mathOps[SUB]=sub_;
mathOps[MUL]=mul_;
mathOps[DIV]=div_;
for(i=ADD;i<=DIV;i++)
{
printf("results are: %d\n", mathOps[i](3, 3));
}
getchar();
return 0;
}
int add_(int a, int b)
{
return a + b;
}
int sub_(int a, int b)
{
return a - b;
}
int mul_(int a, int b)
{
return a * b;
}
int div_(int a, int b)
{
return a / b;
}
I have the following code:
typedef struct{
int A;
char* B;
}MYTYPE;
MYTYPE sample;
int nCount;
void doSomething(int A, MYTYPE* B)
{
//doing something inside this function.
}
doSomething(nCount, &sample);
Is there a way in my function doSomething() to check if the second argument passsed was exactly sample?
Yes, you can simply compare the addresses.
Remember that a pointer to something is actually the address of that something. So you could do like this:
void doSomething(int A, MYTYPE* B)
{
if (B == &sample)
{
printf("B is sample\n";
}
}
Yes:
if(B == &sample)
{
printf("Get your own, don't use sample!\n");
}
note that your call is wrong, you need:
doSomething(nCount, &sample);
^
|
IMPORTANT!
Since the function expects an address. It will not build, as written in the question.
Suppose I have these three functions:
bool A();
bool B();
bool C();
How do I call one of these functions conditionally using a function pointer, and how do I declare the function pointer?
You can do the following:
Suppose you have your A,B & C function as the following:
bool A()
{
.....
}
bool B()
{
.....
}
bool C()
{
.....
}
Now at some other function, say at main:
int main()
{
bool (*choice) ();
// now if there is if-else statement for making "choice" to
// point at a particular function then proceed as following
if ( x == 1 )
choice = A;
else if ( x == 2 )
choice = B;
else
choice = C;
if(choice())
printf("Success\n");
else
printf("Failure\n");
.........
.........
}
Remember this is one example for function pointer. there are several other method and for which you have to learn function pointer clearly.
I think your question has already been answered more than adequately, but it might be useful to point out explicitly that given a function pointer
void (*pf)(int foo, int bar);
the two calls
pf(1, 0);
(*pf)(1, 0);
are exactly equivalent in every way by definition. The choice of which to use is up to you, although it's a good idea to be consistent. For a long time, I preferred (*pf)(1, 0) because it seemed to me that it better reflected the type of pf, however in the last few years I've switched to pf(1, 0).
Declare your function pointer like this:
bool (*f)();
f = A;
f();
Initially define a function pointer array which takes a void and returns a void.
Assuming that your function is taking a void and returning a void.
typedef void (*func_ptr)(void);
Now you can use this to create function pointer variables of such functions.
Like below:
func_ptr array_of_fun_ptr[3];
Now store the address of your functions in the three variables.
array_of_fun_ptr[0]= &A;
array_of_fun_ptr[1]= &B;
array_of_fun_ptr[2]= &C;
Now you can call these functions using function pointers as below:
some_a=(*(array_of_fun_ptr[0]))();
some_b=(*(array_of_fun_ptr[1]))();
some_c=(*(array_of_fun_ptr[2]))();
bool (*FuncPtr)()
FuncPtr = A;
FuncPtr();
If you want to call one of those functions conditionally, you should consider using an array of function pointers. In this case you'd have 3 elements pointing to A, B, and C and you call one depending on the index to the array, such as funcArray0 for A.
You can declare the function pointer as follows:
bool (funptr*)();
Which says we are declaring a function pointer to a function which does not take anything and return a bool.
Next assignment:
funptr = A;
To call the function using the function pointer:
funptr();
Note that when you say:
bool (*a)();
you are declaring a of type "pointer to function returning bool and taking an unspecified number of parameters". Assuming bool is defined (maybe you're using C99 and have included stdbool.h, or it may be a typedef), this may or may not be what you want.
The problem here is that there is no way for the compiler to now check if a is assigned to a correct value. The same problem exists with your function declarations. A(), B(), and C() are all declared as functions "returning bool and taking an unspecified number of parameters".
To see the kind of problems that may have, let's write a program:
#include <stdio.h>
int test_zero(void)
{
return 42;
}
static int test_one(char *data)
{
return printf("%s\n", data);
}
int main(void)
{
/* a is of type "pointer to function returning int
and taking unspecified number of parameters */
int (*a)();
/* b is of type "pointer to function returning int
and taking no parameters */
int (*b)(void);
/* This is OK */
a = test_zero;
printf("a: %d\n", a());
a = test_one; /* OK, since compiler doesn't check the parameters */
printf("a: %d\n", a()); /* oops, wrong number of args */
/* This is OK too */
b = test_zero;
printf("b: %d\n", b());
/* The compiler now does type checking, and sees that the
assignment is wrong, so it can warn us */
b = test_one;
printf("b: %d\n", b()); /* Wrong again */
return 0;
}
When I compile the above with gcc, it says:
warning: assignment from incompatible pointer type
for the line b = test_one;, which is good. There is no warning for the corresponding assignment to a.
So, you should declare your functions as:
bool A(void);
bool B(void);
bool C(void);
And then the variable to hold the function should be declared as:
bool (*choice)(void);
bool (*fptr)();
int main(void)
{
...
...
printf("Enter your choice");
scanf("%d",&a);
switch(a)
{
case 0:
fptr = A;
break;
case 1:
fptr = B;
break;
case 2:
fptr = C;
break;
case 3:
break;
}
(*fptr)();
return 0;
}
Your choice is stored in a. Then accordingly, functions are assigned in the function pointer. Finally, depending on your choice, the very same function is called to return the desired result.
The best way to read that is the clockwise/spiral rule by David Anderson.
Calling a function through a function pointer
float add(int, float), result;
int main()
{
float (*fp)(int, float);
float result;
fp = add;
result = add(5, 10.9); // Normal calling
printf("%f\n\n", result);
result = (*fp)(5, 10.9); // Calling via a function pointer
printf("%f\n\n", result);
result = (fp)(5, 10.9); // Calling via function pointer. The
// indirection operator can be omitted
printf("%f", result);
getch();
}
float add(int a, float b)
{
return a+b;
}
>
Output
15.90000
15.90000
15.90000
You declare a function pointer variable for the given signature of your functions like this:
bool (* fnptr)();
you can assign it one of your functions:
fnptr = A;
and you can call it:
bool result = fnptr();
You might consider using typedefs to define a type for every distinct function signature you need. This will make the code easier to read and to maintain. i.e. for the signature of functions returning bool with no arguments this could be:
typdef bool (* BoolFn)();
and then you can use like this to declare the function pointer variable for this type:
BoolFn fnptr;
Slightly different approach:
bool A() {...}
bool B() {...}
bool C() {...}
int main(void)
{
/**
* Declare an array of pointers to functions returning bool
* and initialize with A, B, and C
*/
bool (*farr[])() = {A, B, C};
...
/**
* Call A, B, or C based on the value of i
* (assumes i is in range of array)
*/
if (farr[i]()) // or (*farr[i])()
{
...
}
...
}
If you need help with complex definitions, like
double (*(*pf)())[3][4];
take a look at my right-left rule here.
//Declare the pointer and asign it to the function
bool (*pFunc)() = A;
//Call the function A
pFunc();
//Call function B
pFunc = B;
pFunc();
//Call function C
pFunc = C;
pFunc();
I usually use typedef to do it, but it may be overkill, if you do not have to use the function pointer too often..
//assuming bool is available (where I come from it is an enum)
typedef bool (*pmyfun_t)();
pmyfun_t pMyFun;
pMyFun=A; //pMyFun=&A is actually same
pMyFun();
This has been more than adequately answered, but you may find this useful: The Function Pointer Tutorials. It is a truly comprehensive treatment of the subject in five chapters!