In an interview I was asked to write an efficient program such that for each integer value given, a function is called.
For example: if user enters 1 then function one will get executed if user enters 5 then function five gets executed and so on..
I was not able to come up with an efficient idea, like we can't use an if statement for checking the value entered and then executing the corresponding functions.
Is there any way we can do this in an efficient manner?
One of the option would be using function pointers, as below.
Declares a type of a void function
typedef void (*fp)();
define your functions
void func1()
{}
.
.
.
void func10()
{}
declare array of function pointers like below
fp function_pointers[10]; //declares the array
Initialize the function pointers like below
function_pointers[0] = func1()
.
.
function_pointers[9] = func10()
Call function using function pointers like below
for (int i=0;i<10;i++)
function_pointers[i]();
Use function pointers.
Simple example:
#include <stdio.h>
//pointer to a void function declaration
typedef void(*someFunc)();
void f1() {
printf("f1 function call\n");
}
void f2() {
printf("f2 function call\n");
}
void f3() {
printf("f3 function call\n");
}
//array of function pointers
const someFunc funcTable[] = {
f1,
f2,
f3
};
int main() {
uint number = 0;
printf("Enter 0, 1 or 2\n");
scanf("%u",&number);
if(number < 3) {
funcTable[number]();
}
}
Related
I have a program in which te type of function to be used has to be different according to a string (the mode). Suppose i want the functions in extfunc to be initiated according to the value i write in some strings, that i have the following situation.
I have a number of functions
void f1_mod1(...)
{
//do domething
}
void f1_mod2(...)
{
//do something else
}
void f2_mod1(...)
{
//do something 2
}
void f2_mod2(...)
{
//do something 2
}
and I want them to be used according to some configurational strings fXn, where X = 1, 2, as in
void extfunc(...)
{
// ...
char *f1n = "mod1";
char *f2n = "mod2";
void (*__f1__)(), (*__f2__)();
__thefunctioniwouldlike(f1n, __f1__, f2n, __f2__);
// execute f1_mod1
__f1__(...);
// execute f2_mod2
__f2__(...);
}
where
void __thefunctioniwouldlike(char *f1n, void *__f1__, char *f2n, *__f2__)
{
if (strcmp(f1n, "mod1") == 0)
__f1__ = f1_mod1;
else if (strcmp(f1n, "mod2") == 0)
__f1__ = f1_mod2;
else
__f1__ = NULL;
if (strcmp(f2n, "mod1") == 0)
__f2__ = f2_mod1;
else if (strcmp(f1n, "mod2") == 0)
__f2__ = f2_mod2;
else
__f1__ = NULL;
}
is a function that takes the configurational strings and assign the function pointers to one of my functions above so that when they are called execute the assigned function.
For completeness:
fX_modX are the functions that take certain arguments and do different stuff both based on the mod variable fXn encoded in a string and __thefunctioniwouldlike is a function that takes as argument the pointers to functions to initiate them according to the value of strings fXn. How can i pass the pointer to pointers to void functions void (*__f1__)() so that in the end executing __fX__ in extfunc will execute fX_modY or fX_modY based on the assignment inside __thefunctioniwouldlike?
Thanks in advance.
How can i pass the pointer to pointers to void functions void (*__f1__)() so that in the end executing __fX__ in extfunc will execute fX_modY or fX_modY based on the assignment inside __thefunctioniwouldlike?
As ever, in C function arguments are passed by value. If you want a called function to modify an object that is local to the caller, then you must pass the address of that object to the function, and the function must modify it indirectly. That applies just the same when that object has pointer type, including function pointer type, as when it has any other type.
Type names can get pretty hairy, however, especially when function pointers are involved. Typedefs can help. I would recommend something along these lines:
// declare f1_func and f2_func as aliases for function types
typedef void (f1_func)(/* ... f1 parameters ... */);
typedef void (f2_func)(/* ... f2 parameters ... */);
// the actual functions must have parameter lists matching the expected ones
// for the corresponding typedefed function types
void mod1_f1(/* parameters */) {
// ...
}
void mod1_f2(/* parameters */) {
// ...
}
void mod2_f1(/* parameters */) {
// ...
}
void mod2_f2(/* parameters */) {
// ...
}
// Functions cannot be handled as objects. You need to use function pointers, instead,
// such as a f1_func * or a f2_func *.
//
// But then you need a second level of indirection to allow a function to manipulate
// function pointers that are local to the caller.
void set_module_functions(const char *f1_module, f1_func **f1,
const char *f2_module, f2_func **f2) {
// Note: Function names such as mod1_f1 are automatically converted to pointers
// in some case:
*f1 = mod1_f1;
// in another case:
*f1 = mod2_f1;
// in some case:
*f2 = mod1_f2;
// in another case:
*f2 = mod2_f2;
}
void the_caller(/* ... */) {
f1_func *f1;
f2_func *f2;
// Pass the addresses of the function pointers:
set_module_functions("mod1", &f1, "mod2", &f2);
// Functions can be (in fact, always are) invoked through function pointers.
// There is no need to dereference a function pointer to call the pointed-to
// function.
f1(/* arguments */);
f2(/* arguments */);
}
Assuming the functions take the same number and type of arguments¹, you can declare an array of function pointers and assign to each pointer the address of a function:
void (*foo[SIZE]) (void) = { &f1_mod, &f2_mod,
&f3_mod, &f4_mod };
Pass the array to the function as:
__thefunctioniwouldlike (foo);
The function declaration can be written as:
void __thefunctioniwouldlike (void (*foo[]) (void), ...);
Then assign it to __f1__ as:
__f1__ = foo[0];
In a similar vein, instead of passing the char * as separate arguments, you can declare an array of char *s:
char *ret[SIZE] = { "mod1", "mod2", "mod3", "mod4" };
Pass it to the function as:
__thefunctioniwouldlike (foo, ret);
The function declaration can be written as:
void __thefunctioniwouldlike (void (*foo[]) (void), char *ret[]);
Compare the string pointed to by the pointer as:
strcmp (ret[0], "foo1");
Execute the function pointed to by the zeroth member of the array as:
(*foo[0])();
Or simply:
foo[0]();
Sample code:
/* Note: I am not very fond of `typedef`s,
* but they could help with readability here.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void f1_mod (void) { }
static void f2_mod (void) { }
static void f3_mod (void) { }
static void f4_mod (void) { }
static void func (void (*foo[])(void), char *ret[], void (**tmp)(void)) {
if (!strcmp (ret[0], "mod1")) {
*tmp = foo[0];
}
}
int main (void)
{
void (*foo[]) (void) = { &f1_mod, &f2_mod, &f3_mod, &f4_mod };
void (*tmp) (void) = 0;
char *ret[] = { "mod1", "mod2", "mod3", "mod4" };
func (foo, ret, &tmp);
return EXIT_SUCCESS;
}
[1] — If that's not true, you can still follow the same approach, and call internal functions inside with the relevant arguments.
For example:
static void f1_mod1 (void)
{
f1_mod1_internal (...);
}
Alright, this is my first post ever in StackOverflow, I have TRIED everything for this. So first instruction is that I need to make a function pointer inside a struct. No problems so far with that.
typedef struct Function2D {
float (*Fun2D) (float);
}Function2D;
The teacher wants this struct function pointer to multiply a given float number by two. I already did that.
int main()
{
Function2D Funcion;
Funcion.Fun2D = Test;
Funcion.Fun2D(10000);
return 0;
}
float Test (float n)
{
n = n*2;
return n;
}
However I the teacher wants to implement another function that returns a Boolean after getting a data type Function2D or the result of the multiplication. Is there a way to access the result of the function pointer from a struct without hardcoding a value?
If I understand your question correctly, then you are asking how to implement a function
returning a bool that takes a function as an argument
OR
that takes a structure containing function pointers as an argument.
OR
that pass the result from a call to a function pointer to another function.
Here is an example all three:
#include <stdio.h>
// Define the types for the function pointers you need
typedef float (*FloatFunc) (float);
typedef bool (*BoolFunc) (FloatFunc);
// Declare a structure containing each of the function pointer types defined above.
typedef struct StructContainingFunctionPointers {
FloatFunc FunFloat;
BoolFunc FunBool;
} StructContainingFunctionPointers;
// Declare a function of the same type as FloatFunc
float MultiplyBy2(float n)
{
n = n * 2;
return n;
}
// Declare a function of the same type as BoolFunc
bool TestIfMultiplyBy2(FloatFunc func)
{
return func(2) == 4;
}
// Declare a function that takes StructContainingFunctionPointers as an argument
void TestStructContainingFunctionPointers(StructContainingFunctionPointers Rec) {
// Do a smoke-test of FunFloat
float result = Rec.FunFloat(10000);
// Pass the result of Rec.FunFloat to printf()
printf("Calling FunFloat(10000) returned %.0f.\n", result);
if (result == 10000 * 2)
printf("The float function seems to work.\n");
else
printf("The float function DOES NOT work.\n");
// Do a smoke-test of FunBool
if (Rec.FunBool(Rec.FunFloat))
printf("The bool function seems to work.\n");
else
printf("The bool function DOES NOT work.\n");
}
int main()
{
// Initialize the record.
StructContainingFunctionPointers Rec;
Rec.FunFloat = MultiplyBy2;
Rec.FunBool = TestIfMultiplyBy2;
// Test
TestStructContainingFunctionPointers(Rec);
// Return success
return 0;
}
This is the output from the program:
Calling FunFloat(10000) returned 20000.
The float function seems to work.
The bool function seems to work.
Hey guys I have a question: How can i call a function from an enum structure with pointers?
For example I have this structure:
typedef enum struct_e
{
FUNCTION_ONE,
FUNCTION_TWO,
FUNCTION_THREE,
FUNCTION_FOUR,
} sctruct_t;
And I have a function that receives one of these variables and the parameters of the function (for example an int)
void call_functions(struct_t action, int exemple) {...}
// -> call like this call_functions(FUNCTION_ONE, 45);
And in that function I have to call one of the functions like this one:
void function_one(int a)
{
printf("You have %d years old", a);
}
Assuming each of the functions to call has type void (*)(int), you can create an array of function pointers, using the enum values as the array index:
typedef void (*call_func_type)(int);
call_func_type func_list[] = {
[FUNCTION_ONE] = function_one,
[FUNCTION_TWO] = function_two,
[FUNCTION_THREE] = function_three,
[FUNCTION_FOUR] = function_four
}
Then call_functions would just index into that array:
void call_functions(struct_t action, int example)
{
func_list[action](example);
}
I usually find that the first step when dealing with a function pointer is to use a typedef to make the syntax more readable. Then, such pointers can be used much like any other data type.
// declares function_ptr as a new type, pointer to function taking an integer parameter and returning void
typedef void (*function_ptr)(int);
// define function pointer p and initialize to point at function one
function_ptr p = function_one;
// call function_one passing 7 as a parameter
(*p)(7);
In this case, assuming that all of the functions take an integer as a parameter, we can use a table of pointers to represent all the functions you'd want to call:
function_ptr table[]=
{
function_one,
function_two,
function_three,
function_four,
};
At this point it's fairly easy to call any number of functions using this method.
void call_functions(struct_t action, int exemple)
{
if( action >= FUNCTION_ONE && action <= FUNCTION_FOUR )
{
(table[action])(exemple);
}
else
{
printf("Unrecognized function %i. Check that function table is up to date\n", (int)action);
}
}
I am trying a write a program that prints a pyramid by calling a function (pass by value and not pass by address).
Well, the function is just supposed to run a for loop to print the pyramid but the actual printing statement is written in the main. The rest of the program seems fine but there is an error in the function call.
Can you please tell me what I am doing wrong? It is the syntax that I am having trouble with. The error is "argument of type void is incompatible with parameter type of 'constant char*'"
#include<stdio.h>
void pyramid(int); //function declaration
int main()
{
int r1;
printf("Enter the number of rows you would like printed:");
scanf("%d",&r1);
printf(pyramid(r1)); //function call
return 0;
}
void pyramid(int r2) //function definition
{
int i,j;
for(i=r2;i>=1;i--)
{
for(j=r2;j<=i;j--)
{
printf("*");
}
printf("\n");
}
}
void pyramid(int); //function declaration
Here the function pyramid will not return any value,
But you are expecting it to return a value in the below statement
printf(pyramid(r1)); //function call
Also this program would run in to an infinite loop,
Here:
for(i=r2;i>=1;i--)
{
for(j=r2;j<=i;j--) //**j will always be less than i**
{
printf("*");
}
printf("\n");
}
printf's prototype is
int printf(const char *restrict format, ...);
But you are trying to pass void to it by calling printf(pyramid(r1));. Call function directly like pyramid(r1); instead of printf(pyramid(r1));.
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!