I have two functions that look like the ones down below and I am trying to merge the two with a function called function3 however I don't want it to check the parameter 'function' everytime it enters the while loop as it is a very poor way to do it. I am wondering if I can merge the two with only one if statement.
void function1(){
int value,a,b;
while(condition){
value=a*b;
}
}
void function2(){
int value,a,b;
while(condition){
value=a+b;
}
}
//merge two functions
void function3(int function){
int value,a,b
while(condition){
if(function==1){
value=a*b;
}
else{
value=a+b;
}
}
}
It is not clear from the code you posted what you intent to do, since you don't actually do anything with the values you calculated.
Aside, I think that you are looking for an array of functions or an array of pointers to functions.
You can use the variable function to access the function that you need, assuming it matches the array index of that function.
int function1(int a, int b) {
return a * b;
}
int function2(int a, int b) {
return a + b;
}
int (*f[])(int, int) = { function1, function2 };
void call_function(int function, int a, int b) {
// check that "function" is within bounds of the array
if (function < 0 || function >= sizeof(f) / sizeof(f[0])) {
// handle out of bounds
}
// call appropriate function
int ret_val = f[function](a, b);
return;
}
Related
One of the common use cases I've come across when I read about function pointers is that they can be used to make a function more flexible, as part of the functionality of the function can be taken in as a parameter. An example for this is qsort where I can make a compare function to decide what is meant by greater and lesser (ascending, descending, is a multiple of,etc) and pass the compare funtion pointer to qsort function.
Here, the function repeat has addptr as parameter and therefore performs multiplication.
int add(int a, int b)
{
return a+b;
}
int (*addptr)(int,int);
int repeat(int a,int b,int (*funcptr)(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=(*funcptr)(ans,b);
}
return ans;
}
int main()
{
addptr=&add;
printf("%d\n",repeat(7,5,addptr));
return 0;
}
But the same exact thing can be done without function pointers at all!
int add(int a, int b)
{
return a+b;
}
int repeat(int a,int b,int func(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=func(ans,b);
}
return ans;
}
int main()
{
printf("%d\n",repeat(7,5,add));
return 0;
}
So why is this even one of the uses of function pointers?
What is the advantage of the first code over the second?
There is a rule C11 6.7.6.3/8 saying that if you write a function inside a parameter list, it will get adjusted to a pointer to function of that type:
A declaration of a parameter as ‘‘function returning type’’ shall be
adjusted to ‘‘pointer to function returning type’’,
This works similar to when you write an array as function parameter, it gets adjusted to a pointer to the first element.
That being said, it is not really meaningful to write a function as a parameter, it is just very confusing to the reader. Use function pointers instead.
EDIT
For maximum readability, I would personally recommend using this style:
typedef int operation_t (int, int);
int repeat (int a, int b, operation_t* operation)
{ ...
Though the most commonly used style is perhaps this one:
typedef int (*operation_t) (int, int);
int repeat (int a, int b, operation_t operation)
{ ...
I prefer the former since hiding pointers behind typedefs is a bad idea, and since that style makes function pointers consistent with regular pointers.
As noticed in comment by #user2390668, func in repeat in already a function pointer. And when you call it, add decays to a function pointer.
If your question is what is a possible use case for a variable holding a function pointer, we must try to imagine a use case where a function will not only be passed as a parameter, but will have to be stored. An example for that would be simulating polymorphism of structs in C. Here is an oversimplified example:
#include <stdio.h>
struct Base {
/* common member variables
...
*/
const char *name;
void (*display)(void *, FILE *fd);
};
struct S1 {
struct Base base;
/* other member variables */
};
void _S1_display(void *this, FILE *fd) {
struct S1 *s1 = this;
fprintf(fd, "In S1, name: %s\n", s1->base.name);
}
struct S2 {
struct Base base;
/* other member variables */
};
void _S2_display(void *this, FILE *fd) {
struct S2 *s2 = this;
fprintf(fd, "In S1, name: %s\n", s2->base.name);
}
void process(void *this, FILE *fd) {
struct Base *base = this; /* valid because base is first element of both S1 and S2 */
base->display(this, fd);
}
int main() {
struct S1 s1 = { "s1", &_S1_display };
struct S2 s2 = { "s2", &_S2_display };
process(&s1, stdout);
process(&s2, stdout);
return 0;
}
Ok, fur such a simply example, polymorphism would not be necessary, but as I said it is oversimplified...
You may use pointers to functions when you need a little more abstraction.
For example, you may want to manage a table of operators that a generic function should use:
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mult(int a, int b) {
return a*b;
}
int div(int a, int b) {
return a/b;
}
void doit(int a,int b,int (*ptr[2])(int,int)) {
printf("%d\n",ptr[0](a,b));
printf("%d\n",ptr[1](a,b));
}
int main() {
int (*ptr[2])(int,int);
printf("additives (1) or multiplicatives (2) ?");
int choice;
scanf("%d",&choice);
switch(choice) {
case 1:
ptr[0] = &add;
ptr[1] = ⊂
break;
default:
ptr[0] = &mult;
ptr[1] = ÷
break;
}
doit(7,5,ptr);
return 0;
}
Of course you can also design a doit function with two pointers but sometimes a table is more convenient (think about a variable length table of function pointers for example, I know even in this case we may use a variable arguments list...).
At least, passing a function pointer in parameter is defining a function pointer variable...
Another example is also implementing in C object oriented programming, where you may implement methods as function pointers members.
In c, we have to define all the functions globally. while studying function pointer i got some program where programmer passes function name as parameter to other function. so why we need to pass function to other function if they all are globally defined?
here i am giving small sample program :
#include<stdio.h>
void bsort(int arr[],int n,int (*compare)(int,int)) //bubble sort
{
int i,j,temp;
for(i=0;i<n;i++){
for(j=0;j<n-i-1;j++){
if(compare(arr[j],arr[j+1]) > 0 ){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int compare(int a,int b)
{
if(a > b) return 1;
return -1;
}
void main()
{
int i;
int arr[5]={6,5,1,9,2};
bsort(arr,5,compare);
for(i=0;i<5;i++)
printf("%d ",arr[i]);
}
in this code, if we remove 3rd argument in definition and calling part of bsort function then also our program will give us same output.so for function pointer this program doesn't make sense.
can you please do some modification in this code and make it good example for function pointer.
Thanks.
Your code does not actual need passing functions as parameters. But your example is rather didactic to make you understand how function pointers work.
However it's important to understand them as they might become very useful especially when dealing with libraries loaded at runtime. There are tons of examples where function pointers are really a good tool.
Here's one:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
double doOperation(double arg, double (*func)(double))
{
return (*func)(arg);
}
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
printf ("%f\n", doOperation(2.0, cosine);
dlclose(handle);
}
You open a library, search for the cosine function, and then pass it as an argument to doOperation.
You can also look here for more info.
Function pointers are used when you might need to change the behavior of your function call depending on some dynamic requirement.
This page sums it up short and sweet:
A function pointer is a variable that stores the address of a function that can later be called through that function pointer. This is useful because functions encapsulate behavior. For instance, every time you need a particular behavior such as drawing a line, instead of writing out a bunch of code, all you need to do is call the function. But sometimes you would like to choose different behaviors at different times in essentially the same piece of code.
A few excellent examples are available there are well.
You pass a function [pointer] to another function because you want to dynamically direct which function the receiver calls. Or more precisely, because the receiver function is built to allow you to do so, thereby requiring you to do so. The pointed-to function does not need to be available at the time the receiver is compiled.
The comparison function required as a qsort() argument is the prototypical example.
Q: Why pass a function to another function?
Without re-writing bsort(), code can sort more than 1 way by only changing the compare function.
#include <stdio.h>
#include <stdarg.h>
int compare_up(int a,int b) {
if(a > b) return 1;
return -1;
}
int compare_down(int a,int b) {
if(a < b) return 1; // reverse the compare
return -1;
}
int compare_random(int a,int b) {
return rand() & 1; // mix them up
}
int main(void) {
int i;
int arr[5]={6,5,1,9,2};
bsort(arr,5,compare_up);
for(i=0;i<5;i++) printf("%d ",arr[i]); puts("");
bsort(arr,5,compare_down);
for(i=0;i<5;i++) printf("%d ",arr[i]); puts("");
bsort(arr,5,compare_random);
for(i=0;i<5;i++) printf("%d ",arr[i]); puts("");
return 0;
}
This is a simple test program where I am trying to get the func function to modify the variables a and b which are then used in the main function. Is there a way to get func to return the modified variables so they can be used? (preferably without using struct as I don't understand how it works)
#include <stdio.h>
void func(int a, int b)
{
a=a+1;
b=b+1;
}
void main(void)
{
int a=0, b=0;
while (1)
{
func(a,b);
printf("%d\n",a);
}
}
If you want to modify variables in the calling function, you have to pass their address to func (i.e. pass a pointer to these variables
void func(int* a, int* b)
{
*a=*a+1;
*b=*b+1;
}
func(&a,&b);
Your code passes its arguments by value. This means that a and b are copied into new variables which are initialised with the values of the calling variables but only exist for the duration of func.
I agree. The best way to do this is using pointers. But are you aware that your code will never terminate? You should use a condition that can end excution of the while loop.
Also, if you wanna perfom the exact same action to both variables you could just use the return statement like this:
#include <stdio.h>
void func(int a, int b)
{
return a+1;
}
void main(void)
{
int a=0, b=0;
while (a < 5)
{
func(a);
func(b);
printf("%d\n",a);
}
}
We can achieve through pointers . Don't use While(1) because it will go to infinite loop. I think following program help to you.
#include <stdio.h>
void func(int* a, int* b)
{
*a=*a+1;
*b=*b+1;
}
void main(void)
{
int a=0, b=0;
//while (1)
// {
func(&a,&b);
printf("%d\n",a);
// }
}
How can i call a function whose name is same as that of the local variable in a calling function
Scenario:
I need to call a function myfun(a,b) from some other function otherfun(int a,int myfun) . How can i do it?
int myfun(int a , int b)
{
//
//
return 0;
}
int otherfun(int a, int myfun)
{
// Here i need to call the function myfun as .. myfun(a,myfun)
// how can i do this?? Please help me out
}
int myfun(int a , int b)
{
return 0;
}
int myfun_helper(int a, int b)
{
return myfun(a,b);
}
int otherfun(int a, int myfun)
{
/* the optimizer will most likely inline this! */
return myfun_helper(a,myfun);
}
You can create a variable keeping a pointer to the myfun() function. This will allow you to effectively 'alias' the original function without introducing an additional one.
int myfun(int a, int b)
{
// ...
return 0;
}
static int (*myfunwrap)(int, int) = &myfun;
int otherfun(int a, int myfun)
{
myfunwrap(a, myfun);
}
Of course, you can replace myfunwrap with any name you like.
The best idea would be to just chose a different name for your parameter. The second best is this one, I think:
int otherfun(int a, int myfun)
{
int myfun_tmp = myfun;
// Here i need to call the function myfun as .. myfun(a,myfun)
{
extern int myfun(int, int);
myfun(a, myfun_tmp);
}
}
I want to use a function to fill different arrays with data by calling that function thrice.
// Function prototype
void fill_array();
int main()
{
int bin_array[15],
prb_array[15],
seq_array[15];
fill_array(bin_array);
fill_array(prb_array);
fill_array(seq_array);
return 0;
}
My question is, what parameters should I put up at the function prototype? All three?
// Function prototype
void fill_array(insert parameter here);
In the prototype, you don't even have to put any name at all, just the type:
void fill_array(int[]);
When you define the function, however, you need a name. However, it can be whatever you want:
void fill_array(int joe[]) {
//...
}
Edit: Although not directly related to the problem at hand, birryree makes an excellent point. You should usually pass the size of an array as well, since otherwise fill_array doesn't know how big the array is:
void fill_array(int[], int);
void do_stuff() {
int bin_array[15],
prb_array[15],
seq_array[15];
fill_array(bin_array, sizeof(bin_array) / sizeof(int));
fill_array(prb_array, sizeof(prb_array) / sizeof(int));
fill_array(seq_array, sizeof(seq_array) / sizeof(int));
}
void fill_array(int bob[], int length) {
for(int i = 0; i < length; i++) {
bob[i] = i * 3;
}
}