abstract function pointers - c

How would I create an array of ten function pointers? What I have is a for loop, and I want to set a function pointer to a different function on each iteration. so:
//pseudocode
for i (0..10)
function = array_of_functions[i];
//...

// Define alias for function pointer type for convenience
typedef void (*action)(int);
// Example function
void print(int) { ... }
action fs[10] = { print, ... };
for (int i = 0; i < 10; ++i)
{
action f = fs[i];
// Call it somehow
f(i * i);
}

This code:
return_t (*array_of_functions[10])(arg1_t, arg2_t);
Declares "array_of_functions" as a 10-element array of function pointers where each pointed-to function takes two arguments of type arg1_t and arg2_t and returns type return_t. Replace types and adjust the number of arguments as appropriate.

Any time you have to deal with ugly function pointer syntax it's better to use a typedef.
#include <iostream>
void a(int i)
{
std::cout<<"a: "<<i<<std::endl;
}
void b(int i)
{
std::cout<<"b: "<<i<<std::endl;
}
typedef void (*fn)(int);
int main(int argc, char**argv)
{
fn foo[2];
foo[0] = a;
foo[1] = b;
for(size_t i = 0; i < sizeof(foo) / sizeof(foo[0]); ++i)
{
foo[i](i);
}
return 0;
}

The simplest way to do it is to create a typedef for your function, and then declare an array with that type. To create a typedef for the function: typedef returntype (*typedefname)(argtype1,argtype2,...,argtypeN); EX:
#include <stdio.h>
#include <stdlib.h>
typedef void (*functype)();
void func1()
{
//...
}
void func2()
{
//..
}
//...
void func10()
{
//...
}
int main(int argc, char* argv[])
{
functype array[] =
{
&func1,
&func2,
&func3,
&func4,
&func5,
&func6,
&func7,
&func8,
&func9,
&func10
};
// Use the array...
return 0;
}

T (*array_of_functions[10])();
Where T is the return type of each function (all functions return the same type, naturally). Things get tricky if you want to store pointers to functions with different numbers/types of parameters:
int foo(void) {...}
int bar(int x) {...}
int bletch(double y, double z) {...}
...
int (*array_of_functions[10])() = {foo, bar, bletch, ...};
If so, you'll have to keep track of what number and types of parameters each function requires somehow so you can call it correctly.
I'm actually kind of down on typedefs for function pointer types; they tend to obscure as much as they simplify.

Related

Call a function using a pointer and pass the pointer that can point to the function along in the parameters

Say that I have a pointer to function theFunc. theFunc takes along a pointer that can point to any function with the same parameter list as theFunc, so the function called can set the passed pointer to NULL or a different function.
Using it would look like this:
while (funcPtr != NULL)
{
funcPtr(&funcPtr);
}
Would defining this be impossible?
Yes, it's doable.
The simple way:
void (*fptr_t)(void*);
The function pointer is data, even though it point to non-data. Therefore a pointer to function pointer can be converted to void* without relying on compiler extensions.
This solution lacks type safety. However, it can be improved.
Currently, it is possible to declare a function taking unspecified number of parameters. It allows to form an incomplete function type. For example:
int foo();
declares a function that returns int and takes unspecified parameters. To have a function taking no parameters use int foo(void).
This allows to declare a function taking a pointer to pointer to incomplete function type:
int foo(int (**)());
// call
int (*fptr)(int (**)()) = foo;
fptr(&fptr);
As mentioned in other answers typedef-ing function types makes the code cleaner.
typedef int foo_aux_f();
typedef int foo_f(foo_aux_f**);
foo_f *fptr = &foo;
fptr(&fptr);
It is possible to improve type safety by nesting the declaration of function types deeper and deeper.
typedef int foo_aux0_f();
typedef int foo_aux1_f(foo_aux0_f**);
typedef int foo_aux2_f(foo_aux1_f**);
typedef int foo_aux3_f(foo_aux2_f**);
typedef int foo_f(foo_aux3_f**);
foo_f fptr = &foo;
fptr(&fptr);
The perfect recursive type would be reached with infinite chain of declaration but in practice 2-3 levels are sufficient.
With some abuse of the syntax of typedef keyword it is possible to squeeze the declaration of this type:
typedef int foo_aux0_f(),
foo_aux1_f(foo_aux0_f**),
foo_aux2_f(foo_aux1_f**),
foo_aux3_f(foo_aux2_f**),
foo_f(foo_aux3_f**);
Unfortunately ... or fortunately, this trick will likely not work in upcoming C23 because the old function declarations without prototypes are planned to be removed from the language making () mean no arguments rather then unspecified number of argument.
Yes, you can pass pointer to pointer to function. The syntax is much easier if you use typedefs.
typedef void somefunc(void);
void func1(void)
{
printf("Func1\r");
}
void func2(void)
{
printf("Func2\r");
}
void swapfunction(somefunc **ptr)
{
if(*ptr == func1) *ptr = func2;
else *ptr = func1;
}
int main(void)
{
somefunc *ptr = NULL;
swapfunction(&ptr);
ptr();
swapfunction(&ptr);
ptr();
}
You can also use function return value:
typedef void somefunc(void);
void func1(void)
{
printf("Func1\r");
}
void func2(void)
{
printf("Func2\r");
}
somefunc *swapfunction(somefunc *ptr)
{
if(!ptr) return func1;
else if (ptr == func1) return func2;
else return NULL;
}
int main(void)
{
somefunc *ptr = NULL;
while(ptr = swapfunction(ptr))
{
ptr();
}
}
Ref your github comment, suggest you use a structure instead of type casting pointers to function pointers, etc. It's not exactly what you are requesting, but kind of.
The code will then look like:
#include <stdio.h>
struct funcArgStruct
{
void (*state)(struct funcArgStruct *);
// int extra_data; // optional
};
typedef struct funcArgStruct funcArg;
void start (funcArg *ptr);
void task1 (funcArg *ptr);
void stop (funcArg *ptr);
/* Implementation of an fsm. */
int main()
{
funcArg ptr_, *ptr = &ptr_;
ptr->state = start;
// ptr->extra_data = 0; // optional
while (ptr->state != NULL)
{
ptr->state(ptr);
}
return 0;
}
void start (funcArg *ptr)
{
ptr->state = task1;
}
void stop (funcArg *ptr)
{
ptr->state = NULL;
}
void task1 (funcArg *ptr)
{
ptr->state = stop;
}
This sort of works:
#include <stdio.h>
void *a(void)
{
printf("Calling a()\n");
return NULL;
}
void *b(void)
{
printf("Calling b()\n");
return a;
}
void *c(void)
{
printf("Calling c()\n");
return b;
}
int main(void)
{
void *(*funcPtr)(void) = &c;
while (funcPtr) {
funcPtr = funcPtr();
}
}
I don't really see good uses, especially in passing the pointer to the function itself as an argument (which I why I omitted it) but whatever floats your boat. You can of course replace the arguments to whatever you need.
You could add a typedef to help out a bit with a type:
typedef void *(*myfunc)(void);
Then you could do the following:
myfunc funcPtr = &c;
// instead of: void *(*funcPtr)(void) = &c;
I don't think any of this is particularly elegant, but it should work.
Note that it doesn't matter if you assign c or &c to myfunc, or whether you return a or &a from one of the functions.

What is the meaning in C when a function is in another function's name (not in the arguments)?

Why is
"void (*parse(char *op))(int, int)"
written like this? (main added to give use case), it gets called from a pointer "fun" with argv[2] without the ints (line 18)... and then again as "fun" with the ints (line 21)?
void (*parse(char *op))(int, int)
{
if (!strcmp(op, "+"))
return(other stuff...);
else
return (0);
}
int main(int argc, char *argv[]){
int a;
int b;
void (*fun)(int, int);
if (argc == 4){
a = atoi(argv[1]);
fun = parse(argv[2]);
b = atoi(argv[3]);
if (fun)
fun(a, b);
else
return(0);
}
return(0);
}
How does it technically work, and it is just a showoff with a simpler way to write it or is this the only correct grammar?
parse() is a function that returns a function pointer. You can use typedef with the type of the returned function to make it look a lot nicer, though:
#include <string.h>
#include <stdlib.h>
// parser_func describes a function that takes two ints and returns nothing
typedef void (*parser_func)(int, int);
// Like this one.
void somefunc(int a, int b) {}
// And parse() is a function that takes a char* and returns a
// pointer to a function that matches parser_func.
parser_func parse(char *op) {
if (!strcmp(op, "+"))
return somefunc;
else
return NULL;
}
int main(int argc, char *argv[]) {
int a;
int b;
parser_func fun; // Function pointer
if (argc == 4) {
a = atoi(argv[1]);
fun = parse(argv[2]); // Assign a function to fun
b = atoi(argv[3]);
if (fun) {
fun(a, b); // And call it if it's not null
}
}
return 0;
}
Why is void (*parse(char *op))(int, int) written like this?
Because that is the syntax for returning a pointer to function. The return type is void (*)(int, int) which is a pointer to function that returns void and accepts two int arguments.
Usually, type aliases are used to make pointers to functions more readable:
typedef void operation(int, int);
using operation = void (int, int); // equivalent C++ alternative
operation* parse(char *op);

A weird type of defining a function

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;
}

How to use structs, pointers and a function in C?

I have learned how to use functions and structs and pointers. I want to combined them all into one. But the code that I write doesn't seem to work. The compiler tells me the test is an undeclared identifier. Here is the code:
#include <stdio.h>
#include <stdlib.h>
struct character
{
int *power;
};
void test (use_power)
int main ()
{
test (use_power)
printf("%d\n",*power);
return 0;
}
void test ()
{
int use_power = 25;
struct character a;
a.power = &use_power;
}
Your code has many mistakes it can't even compile
Multiple missing semicolons.
Implicit declaration of test() here
test (use_power)
with a missing semicolon too.
power is not declared in main().
This line
void test use_power()
does not make sense and is invalid, and also has no semicolon.
The a instance in test() defined at the end is local to test() and as such will be deallocated when test() returns. The use_power int, has exactly the same problem and trying to extract it's address from the function is useless because you can't access it after the function has returned.
I have no idea what you were trying to do, but this might be?
#include <stdio.h>
#include <stdlib.h>
struct character {
int *power;
};
/* Decalre the function here, before calling it
* or perhaps move the definition here
*/
void test(struct character *pointer);
/* ^ please */
int
main(void) /* int main() is not really a valid signature */
{
struct character instance;
test(&instance);
if (instance.power == NULL)
return -1;
printf("%d\n", *instance.power);
free(instance.power);
return 0;
}
void
test(struct character *pointer)
{
pointer->power = malloc(sizeof(*pointer->power));
if (pointer->power != NULL)
*pointer->power = 25;
}
Your code seems to be wrong. Your definition for test contains no arguments as
void test ()
{
int use_power = 25;
struct character a;
a.power = &use_power;
}
but your prototype contains one argument
void test (use_power)
which is wrongly put. First there are no semicolons; at the end of your prototype declaration, secondly by looking at your code, use_power is a variable and not a datatype so it cannot be present solely in a function declaration.
You will get an argument mismatch error.
You have used the line in main()
printf("%d\n",*power);
which is absolutely wrong. you cannot access any member of a structure without a structure variable.
And again, you have not mentioned the; after your call to the incorrect test()before this line
As you have not put your question so properly, I must figure out what you wish to achieve. I bet you want to hold the address of a integer in the pointer member of a structure and then print its value.
Below is a code snippet which will work as you desire.
#include <stdio.h>
#include <stdlib.h>
struct character
{
int *power;
};
struct character a; //define a structure variable
void test ();
int main ()
{
test ();
printf("%d\n",*(a.power)); // print the member of structure variable a
return 0;
}
void test ()
{
int use_power = 25;
a.power = &use_power;
}
example
#include <stdio.h>
struct character {
int *power;
};
void test(struct character *var);
int main (void){
struct character use_power;
int power = 5;
use_power.power = &power;
test(&use_power);
printf("%d\n", power);
return 0;
}
void test(struct character *var){
int use_power = *var->power;
*var->power = use_power * use_power;
}

How do I declare a function that returns a function pointer?

Imagine a function myFunctionA with the parameter double and int:
myFunctionA (double, int);
This function should return a function pointer:
char (*myPointer)();
How do I declare this function in C?
typedef is your friend:
typedef char (*func_ptr_type)();
func_ptr_type myFunction( double, int );
void (*fun(double, int))();
According to the right-left-rule, fun is a function of double, int returning a pointer to a function with uncertain parameters returning void.
EDIT: This is another link to that rule.
EDIT 2: This version is only for the sake of compactness and for showing that it really can be done.
It is indeed useful to use a typedef here. But not to the pointer, but to the function type itself.
Why? Because it is possible to use it as a kind of prototype then and so ensure that the functions do really match. And because the identity as a pointer remains visible.
So a good solution would be
typedef char specialfunc();
specialfunc * myFunction( double, int );
specialfunc specfunc1; // this ensures that the next function remains untampered
char specfunc1() {
return 'A';
}
specialfunc specfunc2; // this ensures that the next function remains untampered
// here I obediently changed char to int -> compiler throws error thanks to the line above.
int specfunc2() {
return 'B';
}
specialfunc * myFunction( double value, int threshold)
{
if (value > threshold) {
return specfunc1;
} else {
return specfunc2;
}
}
Make a typedef:
typedef int (*intfunc)(void);
int hello(void)
{
return 1;
}
intfunc hello_generator(void)
{
return hello;
}
int main(void)
{
intfunc h = hello_generator();
return h();
}
char * func() { return 's'; }
typedef char(*myPointer)();
myPointer myFunctionA (double, int){ /*Implementation*/ return &func; }

Resources