I am writing a program in C which uses an array of function pointers. If I do not include an argument I am able to call the functions with my code without an issue.
int (*functionsArray[2][3])() = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
However when I try and pass the argument int x:
int (*functionsArray[2][3])(int x) = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
I get an error:
invalid conversion from 'int (*)()' to 'int (*)(int)'
Also none of these functions return an int, shouldn't I be able to declare them as void?
void(*functionsArray[2][3])(int x) = {
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
Trying this results in an error:
error: invalid conversion from 'int (*)()' to 'void (*)(int)'
Thanks.
That will work fine, provided you declare the functions correctly:
#include <stdio.h>
int functionOne(int x) { return 1; }
int functionTwo(int x) { return 2; }
int functionThree(int x) { return 3; }
int functionFour(int x) { return 4; }
int functionFive(int x) { return 5; }
int functionSix(int x) { return 6; }
int (*functionsArray[2][3])(int x) = {
{functionOne, functionTwo, functionThree},
{functionFour, functionFive, functionSix}
};
int main (void) {
printf ("%d\n", (functionsArray[0][1])(99));
printf ("%d\n", (functionsArray[1][2])(99));
return 0;
}
The output of that program is 2 and 6.
It will also work if you want no return value:
#include <stdio.h>
void functionOne(int x) { puts ("1"); }
void functionTwo(int x) { puts ("2"); }
void functionThree(int x) { puts ("3"); }
void functionFour(int x) { puts ("4"); }
void functionFive(int x) { puts ("5"); }
void functionSix(int x) { puts ("6"); }
void (*functionsArray[2][3])(int x) = {
{functionOne, functionTwo, functionThree},
{functionFour, functionFive, functionSix}
};
int main (void) {
(functionsArray[0][1])(99);
(functionsArray[1][2])(99);
return 0;
}
That program also outputs 2 and 6, as expected.
It all comes down to ensuring that the function declarations match the type given in the array.
When you declare an array:
int (*functionsArray[2][3])(int x) =
{
{functionOne,functionTwo,functionThree},
{functionFour,functionFive,functionSix}
};
every element of the array has to be of type int (*)(int). Otherwise, the compiler correctly reports an error.
Take a simple case:
void foo()
{
}
int (*fp)(int x) = foo;
should result in the same compiler error because you are trying to initialize a variable of type int (*)(int) using foo, whose type is void (*)().
Related
I have a function that prints 'Hello' and an integer.
I would like to use a callback function that passes the integer into the first function A.
//FUnction Pointers in C/C++
#include<stdio.h>
void A(int ree)
{
printf("Hello %s", ree);
}
void B(void (*ptr)()) // function pointer as argument
{
ptr();
}
int main()
{
void (*p)(int) = A(int);
B(p(3));
}
Desired result would be 'Hello 3'. This doesn't compile.
#include<stdio.h>
void A(int ree)
{
printf("Hello %d", ree); // format specifier for int is %d
}
void B(void (*ptr)(int), int number) // function pointer and the number as argument
{
ptr(number); //call function pointer with number
}
int main()
{
void (*p)(int) = A; // A is the identifer for the function, not A(int)
B(p, 3); // call B with the function pointer and the number
// B(A, 3); directly would also be possible, no need for the variable p
}
I'm having trouble with macros in C. Is there any way to call and get the value of a parameter in macro to call a function?
The example code below generates an error:
#define order(i) fruits_i##_banana()
void fruits_1_banana()
{
printf("Order banana\n");
}
int main()
{
int a = 1;
order(a);
}
You need to use ## before and after i.
#define order( i ) fruits_##i##_banana()
void fruits_1_banana()
{
printf("Order banana\n");
}
int main()
{
order(1);
}
Note that you cannot pass a to order because macro expansion doesn't take the value of a variable, it just uses the variable name as it is.
References: https://learn.microsoft.com/en-us/cpp/preprocessor/token-pasting-operator-hash-hash?view=msvc-160
Instead, you can use an array of function pointers:
#include <stdio.h>
static void fruits_0_banana(void)
{
printf("Order banana 0\n");
}
static void fruits_1_banana(void)
{
printf("Order banana 1\n");
}
static void (*order[])(void) = {
fruits_0_banana, // Or NULL if you don't need it
fruits_1_banana,
// ...
};
int main(void)
{
int a = 1;
order[a]();
return 0;
}
Incompatible pointer type but I don't understand that it exactly means. Here's the error: "warning: passing argument 1 of 'evenOrOdd' from incompatible pointer type"
#include <stdio.h>
int isEven(int x)
{
if (x % 2 == 0)
{
return x;
}
}
int isOdd(int x)
{
if (x % 2 != 0)
{
return x;
}
}
int evenOrOdd(int (*p_evenOrOdd[2])(int), int x)
{
p_evenOrOdd[0] = isEven;
p_evenOrOdd[1] = isOdd;
if (p_evenOrOdd[0])
{
return p_evenOrOdd[0](x);
}
else
{
return p_evenOrOdd[1](x);
}
}
int main(void)
{
result = evenOrOdd(isEven, 10);
return 0;
}
: "warning: passing argument 1 of 'evenOrOdd' from incompatible pointer type"
int (*p_evenOrOdd[2])(int), as a function parameter to evenOrOdd(), is a pointer to a function pointer.
isEven, when passed in evenOrOdd(isEven, 10), is a function pointer.
A pointer to a function pointer is incompatible with a function pointer.
I suspect OP wants the following but the rest of the function goal is unclear.
// int evenOrOdd(int (*p_evenOrOdd[2])(int), int x)
int evenOrOdd(int (*p_evenOrOdd)(int), int x)
I'm using a function pointer to delegate states in C.
// states
void state1(int first, int second) {
...
}
void state2(int first, int second) {
...
}
// state pointer
void (*current_state)(int, int);
// state logic
if (condition1) {
current_state = &state_1;
} else if (condition2) {
current_state = &state_2;
}
// do the thing
(*current_state)(1, 2);
Now I'm at a point where the given arguments no longer suffice, so there is a third argument needed. Since I don't want to change all states, I wondered if it is possible to pass a quasi constant parameter along with the pointer. Something like this:
void state3(int first, int second, int third) {
...
}
// state logic
...
else if (condition3) {
// calculate the constant third argument
int param3 = 0;
current_state = &state_3(int, int, param3);
}
I there a way to get this to work?
Well I'm not sure I'd recommend it but you could do this sort of thing:
#include <stdlib.h>
#include <stdio.h>
typedef int pfun();
int alice( int a, int b) { return b; }
int bob( int a, int b, int c) { return c; }
int main( )
{
pfun* f;
f = alice;
printf( "%d\n", f( 1, 2, 3));
f = bob;
printf( "%d\n", f( 1, 2, 3));
return EXIT_SUCCESS;
}
This compiles with
gcc -o funp -Wall funp.c
without warnings and runs correctly.
The point is that a function declaration like
int f();
Says that f is a function that returns an int, with unspecified arguments. The downside is that the compiler cannot check that the arguments are of the correct type.
You could pass a *void pointer and cast it to the concrete type in the state function. All state functions will have the same signature. Something like this:
// states
struct state1_args {
int first;
int second;
};
struct state2_args {
float first;
float second;
float third;
};
void state1(void* state_args) {
struct state1_args* args = (struct state1_args*)state_args;
use(args->first);
...
}
void state2(void* state_args) {
struct state2_args* args = (struct state2_args*)state_args;
use(args->third);
...
}
// state pointer
void (*current_state)(void*);
// state logic
if (condition1) {
current_state = &state_1;
current_state_args = &args_1;
} else if (condition2) {
current_state = &state_2;
current_state_args = &args_2;
}
// do the thing
(*current_state)(current_state_args);
I learning C for 1 years, i saw a type of defining a function. I couldn't name it, so i want to know the name of the defining function.
We defining functions as standard:
FunctionReturnType FunctionName(FunctionArgs)
{
codes();
}
But i saw that type:
FunctionReturnType FunctionName(FunctionArgs)(TheWeirdArea)
{
codes();
}
So what we doing for in i named as TheWeirdArea? I guess it's relative with function arguments, but i want to know correctly what we do in TheWeirdArea.
I guess this is about returning a function pointer to a function looking like
FunctionReturnType func(TheWeirdArea);
Here is an example:
#include <stdio.h>
int bar1(int b)
{
printf("bar1\n");
return 42 + b;
}
int bar2(int b)
{
printf("bar2\n");
return 100 + b;
}
int (*foo(int a))(int b) // Returns a function pointer
{
if (a == 1) return bar1;
return bar2;
}
int main(void) {
printf("%d\n", foo(1)(100));
printf("%d\n", foo(2)(200));
return 0;
}
Output:
bar1
142
bar2
300
Hope this dummy example help you
int add(int x,int y)
{
return x+y; //very dummy function return x+y
}
typedef int (*pointer_to_add)(int,int);
/* this is a declaration of function pointer works
with any function has an int return type and
accept two int arguments not only add */
int (*my_function(int arg1, double arg2))(int, int)
{
/*This a function accept an int argument
arg1 and double arg2 and return pointer to a function or address of function
which has a two int type arguments and return an int */
pointer_to_add ptr=add; //ptr is a pointer now to add function.
return ptr;
}
More simple form
pointer_to_add my_function(int arg1,double arg2)
{
pointer_to_add ptr=add;
return ptr;
}
Now in your main code you can use the returned address like:
int main(void)
{
pointer_to_add P=my_function(25,3.5);
printf("%i",p(22,33));
return 0;
}