Can anyone explain these two lines of code in C:
void (*pfs)(void) = &fs;
long int (*pfact)(int) = &fact;
Can anyone explain these two lines of code in C:
void (*pfs)(void) = &fs;
long int (*pfact)(int) = &fact;
To make these declarations more clear
void (*pfs)(void)=&fs;
long int (*pfact)(int)=&fact;
you can introduce typedef names for function declarations as for example
typedef void FUNC1( void );
typedef long int FUNC2( int );
and then write
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
So the original declarations declare pointers to functions of the specified types and initialize them with addresses of the given functions.
Here is a demonstrative program
#include <stdio.h>
typedef void FUNC1( void );
typedef long int FUNC2( int );
void fs( void )
{
puts( "Hello Islacine" );
}
long int fact( int x )
{
return x;
}
int main(void)
{
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
pfs();
printf( "sizeof( long int ) = %zu\n", sizeof( pfact( 0 ) ) );
return 0;
}
Its output might look like
Hello Islacine
sizeof( long int ) = 8
Take into account that instead of
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
or instead of
void (*pfs)(void)=&fs;
long int (*pfact)(int)=&fact;
you could even write
FUNC1 *pfs = fs;
FUNC2 *pfact = fact;
or
void (*pfs)(void) = fs;
long int (*pfact)(int) = fact;
because in expressions with rare exceptions a function designator is converted to pointer to function.
You could even write :)
FUNC1 *pfs = *****fs;
FUNC2 *pfact = *****fact;
or
void (*pfs)(void) = *****fs;
long int (*pfact)(int) = *****fact;
From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)
4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator65) or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
This syntax defines a function pointer. You can use them like this:
void a() {
//do something
}
int main() {
void (*functionPointer)();
functionPointer = a;
//or
functionPointer = &a;
//call the funcion pointer as you would a regular function
functionPointer();
}
The main reasons to use function pointers are to make callback functions and "jump-tables " (This is in quotes because function pointer arrays are not really jump tables. Real jump tables can only be made in assembly language).
what does void(* ) (void) and int(* ) (int) mean in C?
They just mean pointer to function taking void argument and returning void.
void (*pfs)(void)=&fs;
pfs is an pointer to function taking void as an argument and returning void. This has initialized with function of same signature type i.e fs here.
long int (*pfact)(int)=&fact;
pfact is an pointer to function taking int as an argument and reutring long int. After the assignment pfact is pointing to function fact.
Additional Note:
There are tools to read complicated declaration. One of them is https://cdecl.org/. Also as others have pointed out better way to work with pointer to function is typdef them .
They are function pointers. In your example:
void (*pfs)(void)=&fs;
You are creating a variable named "pfs". This variable has the type of a function that takes in no arguments and returns nothing.
The following makes your examples much more clear.
return_type (*variable_name) (argument_list)
Now the right side of the = sign is pretty easy if you understand the first half.
All we do is assign the location of the function "fs" to our function pointer (variable) "pfs".
Here is a full example to demo the explanations above.
#include <stdio.h>
void my_print_method(int number) {
printf("The number is: %d", number);
}
int main() {
// Declare our function pointer variable
void (*printer)(int);
// Assign our function pointer 'printer' to the method 'my_print_method'
printer = &my_print_method
// We can also assign the method to our function pointer as such:
printer = my_print_method
// Use our function pointer as if it were a function
(*printer)(55);
// Keep in mind that that in C we can simply write the function call as such:
printer(55);
}