Calling functions through arrays in C? - c

I am in the middle of writing a program which has a function which runs another function:
int executePuzzle(int input) {
switch (input) {
case 1: puzzle1();break;
case 2: puzzle2();break;
default:break;
}
}
However it may be more efficient to simply have something like:
int puzzle[2] = {puzzle1(),puzzle2()};
Then call puzzle0; I was wondering how this would be done.

It sounds like a place where function pointers would be useful
typedef void (*puzzlePointer)();
puzzlePointer puzzles[] = { puzzle1, puzzle2, puzzle3 };
void executePuzzle(int input) {
if (input >= 0 && input < 2) {
puzzles[input]();
}
}

Use the Function Pointers

When the cases of the switch statement are contiguous like in your executePuzzle function, it is actually likely that the compiler internally uses function pointers (through a jump table) to implement the switch statement.

Related

switch cases and one global variable for each case

I am dealing with a issue with switch cases.
Explanation of the program:
main(argc,argv).
argv leads to cases in a switch statement. Depending on the input, the according case will be entered and the corresponding function will be executed. -> Output is always a struct, with different content. More than one input (i.e. main.c case1 case3) is allowed-> executed both cases.
my problem is dealing with the passing of these data's and save it in a global variable, in order to print the collection. Inside of a case, I am passing the local results to the global variable, but after the break statement of the case, the global starts with NULL again and doesn't contain the info's of the executed case.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "m.h"
output* print;
int main(int argc, char* argv[])
{
output_g* global; // global_struct
if(argc > 1)
{
global= create_global(argc-1); // allocation for global struct
for(int j = 0; j < argc; j++)
{
switch (atoi(argv[i]))
{
case 123:
{
output* print= 123();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 456:
{
output* print= 456();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 789:
{
lfnr++;
output_1* print_liste = 789();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
default:
break;
}
print_global_struct(file,globale_liste);
delete_global(globale_liste);
}//End for-Schleife
}// End If
return 0;
}
a) If I understood you correctly, you don't understand the switch statement :)
A switch statement is similar to nested if statements.
so..
int x = 10;
switch (x)
case 1:
//does not happen, x is not 1
case 10:
//happens ...
after all that x is still 10, unless you changed it in the case statements explicitly. The cases just check to see IF x is a value, it does not SET a value. The same is true for any other variable in your code, the above code would not modify y either, unless you explicitly assign it inside a case it won't change.
b) it is best if you DO NOT declare locals in a case statement. They can become very wonky. The standard c++ rules work: variables declared inside {} pairs are scoped to inside that {} pair, so proper use of them will properly give the correct scope for each case. So it will work as expected if you apply braces. You should NOT declare a local in one case and use it in another, even if you can get it working (you can) it is error prone in that editing the code later can break things, the code can be confusing to read and work with, and its just generally a bad idea.
an example:
int main()
{
int x = 3;
switch(x)
{
case 1: int y;
case 2: y = 3;
case 3: y = 5;
cout << y << endl;
};
}
that compiled and ran for me, printing 5.
It worked fine -- I did not expect that, using g++ c17 options.
I still think it is a bad thing to do as far as reading and following the intent.
if you put {} around the int y statement, it does NOT compile anymore.
If you put breaks after the case 1 and case 2, it does NOT compile anymore.
so it is 'fragile' to being edited, at the very least, to do this.
c) run time won't lose anything. Ive had programs that ran for months on end. Being in a case has no effect on this either. The risk of losing variables is the 'ram' risk that all programs face... if a long running program is killed by power outage or malfunction etc you lose anything not saved to a file and have to start over. Long running programs should save their state periodically to protect against this.

Is There A Different Way To Process Input Other Than "If" Statements?

I am a beginner with C and programming in general (I have been programming with C/C++ for two years now), and the only types of programs I have ever made were command line math processors which take arguments and do operations on them. There is no forking of what is to be done based off of what the input is. I don't know how to do something like that, so what I have been doing recently is designing my programs in a way that is like:
printf("What feature to use?");
int response;
scanf("%d", response);
if (response == 1)
{
feature01();
}
if (response == 2)
{
feature02();
}
... and I continue on like this. For my programs with usually less than 10 unique features, this is OK, but only for the time being. If I ever wrote a program with 50-100 unique branch features, there might be an issue. How can you process input and branch to different features without using the if statement in the fashion above?
You can replace a series of if statements on mutually-exclusive values with switch in many situations:
switch (response)
{
case 1:
feature01();
break;
case 2:
feature02();
break;
default:
featureXX();
break;
}
That's roughly equivalent to:
if (response == 1)
{
feature01();
}
else if (response == 2)
{
feature02();
}
else
{
featureXX();
}
...except that the compiler can optimize the switch a bit more.
You can create a function table. First, a typedef
typedef void (*feature)();
feature now stands for a pointer to a function that takes no arguments and returns void.
Now, write (and notice the index change)
void feature0() {...}
void feature1() {...}
// ...
void feature9() {...}
And then put these into an array:
feature[] actions = {&feature0, &feature1, ..., &feature9};
And then your code becomes (error checking left out):
printf("What feature to use?");
int response;
scanf("%d", &response);
actions[response]();
Pointers to functions get treated as the actual functions when called.

optimizing/ better way of coding a function and using its return value

I have some 20 to 30 functions, i have to call wsse_authenticate, in ever function for, and this wsse_authenticate function returns a value based on that value i send the fault message, Is there any way i can improve this code, so that i just call the function wsse_authenticate(soap) in every function and the switch case be replaced by some better code, i want to make it much efficient, Pls give me some inputs
wsse_ret = (wsse_authenticate(soap));
if(wsse_ret)
{
switch(wsse_ret)
{
case 1: onvif_fault(soap,"ter:NoSecuritytoken","ter:Failed_wsse_Aunthentication");
case 2: onvif_fault(soap,"ter:InvalidUserName","ter:FailedAunthentication");
case 3: onvif_fault(soap,"ter:InvalidPassword","ter:FailedAunthentication");
}
}
From the above code, I see that you are calling same function for all the cases expect for the "failure message" passed as an argument to function onvif_fault. And also there is no break after each case statement which would not give you result as expected.
Explanation for using break statement:
Suppose ret value is 1, then all the three cases would be executed since there is break statement at the end. Which means onvif_fault will be called three times with different parameters which is not expected.
Solution for you question
You can create a table using structures in c which actually has the list of the faults.
This was you can replace your Switch statements with only one line of code.
EX:
typedef struct _fault_messages
{
char msg1[254];
char msg2[254];
} fault_messages;
fault_messages msg_table[3] = {
{"ter:NoSecuritytoken", "ter:Failed_wsse_Aunthentication"},
{"ter:error1", "ter:fault1"},
{"ter:error2", "ter:fault2"}
};
Now, your fault messages in the above table are mapped. You can optimize your code as mentioned below:
wsse_ret = (wsse_authenticate(soap));
if(wsse_ret)
{
onvif_fault(soap, msg_table[wsse_ret-1].msg1, msg_table[wsse_ret-1].msg2);
}
If I understood correctly - your main problem is that you don't want to repeat security checking code in each and every function from 30 function set :-)
If that is the case you can try to use such pattern:
#include <stdio.h>
#include <string.h>
int isUserPasswordValid(char * password) {
return strcmp(password, "MyBigPassword") == 0;
}
#define callFunctionWithAuthentication(password, secPayload, execPayload) \
do {\
if (!isUserPasswordValid(password)) {\
secPayload\
}\
else {\
execPayload\
}\
} while(0);
int myTestFunction(int x) {
return x;
}
int main(int argc,char* argv[]){
// bad password - executes only authentication
callFunctionWithAuthentication(
"randomPassword",
printf("oops - bad password - can't continue\n");,
int a = myTestFunction(10); printf("function returned %d\n",a);)
// good password - executes authentication AND code after
callFunctionWithAuthentication(
"MyBigPassword",
printf("oops - bad password - can't continue\n");,
int a = myTestFunction(10); printf("function returned %d\n",a);)
return 0;
}
Only drawback that you must replace the call of each 30 function into the call of callFunctionWithAuthentication. But this is one-time task. Further you must always call this macro instead of plain function.

efficient function call

I need your help in writing a efficient program.
I have approx 50 functions say call_1(), call_2() ... call_50(). I need to call them based on the index read from a data packet, i.e if the field in data is 25 in need to call call_25(), if 10 then call_10().
I have written this in if else condition like
if (index == 5)
call_5()
elseif (index == 6)
..so on ..
But I think this is not the efficient way of writing. Any other ideas of implementing this scenario?
Can function pointers help here?
Appreciate your help. thanks.
Yes, use a lookup table of function pointers:
typedef void(*fp)(void);
void call_01(void);
void call_02(void);
/* ... */
fp functions[] = { &call_01,
&call_02,
/* ... */
};
void call()
{
unsigned int n = get_index();
functions[n]();
}
If the arguments are same for all 50 functions, use an array of function pointers:
typedef void (*FieldHandler)(void);
const FieldHandler handlers[50] = { call_0, call_1, /* ... and so on ... */ };
Then you just index into the array and call:
handlers[index]();
You can use an array of function pointers there easily, if all your functions have the same signature.
typedef void (*func)(void);
...
func dispatch_table[] = {
func0,
func1,
func2,
...
func50,
};
And later use like this
int function_index = packet_get_func_index( packet );
...
dispatch_table[ function_index ]();
Yes, function pointers are the way to go here.
I would suggest creating a table of function pointers and since your input is an index, you just index into the table to call the right function.
I'd use a switch statement:
switch(index) {
case 1: return call01();
case 2: return call02();
case 3: return call03();
}
This is not a lot more code than using function pointers, and it's (imho) more concise.
Yeah, that is pretty inefficient. I think the best way to proceed is to write a dispatcher of this form in the range of 0 - 255:
void (*dispatcher[255]);
Of course, you would need to assign all the necessary functions instead of doing the if statements, but this would be a heck of a lot faster:
dispatcher['a'] = &call_1;
dispatcher['b'] = &call_2;
dispatcher['c'] = &call_3;
...
Then you can just do:
dispatcher(index) and it would know which function to execute.
Hope that helps.

How to Pass Simple, Anonymous Functions as Parameters in C

I'm sure some variation of this question has been asked before but all other, similar questions on SO seem to be much more complex, involving passing arrays and other forms of data. My scenario is much simpler so I hope there is a simple/elegant solution.
Is there a way that I can create an anonymous function, or pass a line of code as a function pointer to another function?
In my case, I have a series of diverse operations. Before and after each line of code, there are tasks I want to accomplish, that never change. Instead of duplicating the beginning code and ending code, I'd like to write a function that takes a function pointer as a parameter and executes all of the code in the necessary order.
My problem is that it's not worth defining 30 functions for each operation since they are each one line of code. If I can't create an anonymous function, is there a way that I can simplify my C code?
If my request isn't entirely clear. Here's a bit of pseudo-code for clarification. My code is much more meaningful than this but the code below gets the point accross.
void Tests()
{
//Step #1
printf("This is the beginning, always constant.");
something_unique = a_var * 42; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
//Step #2
printf("This is the beginning, always constant.");
a_diff_var = "arbitrary"; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
...
...
//Step #30
printf("This is the beginning, always constant.");
var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; //This is the line I'd like to pass as an anon-function.
printf("End code, never changes");
a_var++;
}
Not in the traditional sense of anonymous functions, but you can macro it:
#define do_something(blah) {\
printf("This is the beginning, always constant.");\
blah;\
printf("End code, never changes");\
a_var++;\
}
Then it becomes
do_something(something_unique = a_var * 42)
No, you cannot. Anonymous functions are only available in functional languages (and languages with functional subsets), and as we all know, c is dysfunctional ;^)
In C and pre-0x C++, no.
In C++0x, yes, using lambda functions.
The best way to simplify your code would probably to put a for loop around a switch statement.
int a_var;
for ( a_var = 0; a_var <= 30; a_var++ )
{
starteroperations();
switch (a_var)
{
case 0:
operation0(); break;
case ...:
operationx(); break;
case 30:
...
}
closingoperations();
}
If you can use Clang, you can take advantage of blocks. To learn blocks, you can use Apple's documentation, Clang's block language specification and implementation notes, and Apple's proposal to the ISO C working group to add blocks to the standard C language, as well as a ton of blog posts.
Using blocks, you could write:
/* Block variables are declared like function pointers
* but use ^ ("block pointer") instead of * ("normal pointer"). */
void (^before)(void) = void ^(void) { puts("before"); };
/* Blocks infer the return type, so you don't need to declare it
* in the block definition. */
void (^after)(void) = ^(void) { puts("after"); };
/* The default arguments are assumed to be void, so you could even
* just define after as
*
* ^{ puts("after"); };
*/
before();
foo = bar + baz*kablooie;
after();
This example gives the anonymous blocks names by assigning to a block variable. You can also define and call a block directly:
^{ puts("!"); } ();
/*| definition | invocation of anonymous function |*/
This also makes defining "struct-objects" (OOP in C using structs) very simple.
Both Clang and GCC support inner/nested functions as an extension to standard C. This would let you define the function immediately before taking its address, which might be an alternative if your control flow structure allows it: inner function pointers cannot be allowed to escape from their immediate scope. As the docs say:
If you try to call the nested function through its address after the containing function has exited, all hell will break loose. If you try to call it after a containing scope level has exited, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it's not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.
Using nested functions, you could write:
/* Nested functions are defined just like normal functions.
* The difference is that they are not defined at "file scope"
* but instead are defined inside another function. */
void before(void) { puts("before"); };
void after(void) { puts("after"); };
before();
foo = bar + baz*kablooie;
after();
Either you go the case way suggested by #dcpomero, or you do the following:
typedef void job(int);
job test1; void test1(int a_var) { something_unique = a_var * 42; }
job test2; void test2(int a_var) { a_diff_var = "arbitrary"; }
job test3; void test3(int a_var) { var_30 = "Yup, still executing the same code around a different operation. Would be nice to refactor..."; }
job * tests[] = { test1, test2, test3, testn };
void Tests()
{
int i;
for (i=0; i < sizeof tests/sizeof tests[0]; i++) {
printf("This is the beginning, always constant.");
tests[i](a_var);
printf("End code, never changes");
a_var++;
}
}

Resources