Function as a function parameter in C - c

void f(int a, char b, char* c) {
if(..) {
...
f(a,b,c); //recursive
}
...
}
void g(int a, double b, char* c, int d) {
if(..) {
...
g(a,b,c,d); //recursive
}
...
}
I want to make a separate function because I use the code within the if statement several times. But this function have to have a function as a parameter becuase I use recursive method. I know that we can use function as a parameters, but in the f function there are 3 parameters, in the g function have 4 parameters.
The code in the if statement in f is the same as the code in the if of g. Except for the function call in that code?
Simply I have no idea how to solve this issue.

You can use union to pack the variable number of arguments, as shown in sample code below.
It may be unusual to use union like this, but it works.
#include<stdio.h>
union u {
struct { int a; char b; char* c; } f;
struct { int a; double b; char* c; int d; } g;
};
void func_u_f (union u* ua) {
printf(" f = {a: %d, b: %c, c:%s}\n", ua->f.a, ua->f.b, ua->f.c);
ua->f.a++;
}
void func_u_g (union u* ua) {
printf(" g = {a: %d, b: %e, c:%s, d:%d}\n",
ua->g.a, ua->g.b, ua->g.c, ua->g.d);
ua->g.a++; ua->g.b *= 2.0; ua->g.d++;
}
void r (int i, void (*func) (union u*), union u* ua) {
if (i < 3) { /* or whatever conditions to terminate recursion */
printf ("Recursion %d\n", i);
func(ua);
r (++i, func, ua);
} else {
printf ("Exit recursion at %d\n", i);
return;
}
}
int main () {
union u u1, u2;
/* f */
u1.f.a = 10; u1.f.b = 'X'; u1.f.c = "I am u.f.";
r(0, &func_u_f, &u1);
/* g */
u2.g.a = 10; u2.g.b = .4e-6; u2.g.c = "I am u.g."; u2.g.d = 98;
r(-2, &func_u_g, &u2);
return 0;
}

I am proposing you an easy fix that doesn't work in general because it involves the use of a sentinel value.
Let's say that the the variable d that you pass to g is always positive. Than you can choose -1 as sentinel value.
You always pass four parameters to the function myIf and then check whether d is -1. If it is, then you call f with three parameters, otherwise you call g.
int main() {
myIf(a, b, c, d);
return 0;
}
void myIf(int a, int b, char *c, int d)
{
if( d == -1 ) {
f(a, b, c);
}
else {
g(a, b, c, d);
}
}

I'm not sure exactly what you're trying to do. But if you're worried about code duplication in the if statements, you can refactor that our to another function:
if (isCondition()) ...
bool isCondition() { return ... }

Related

Passing function to function C [duplicate]

I want to create a function that performs a function passed by parameter on a set of data. How do you pass a function as a parameter in C?
Declaration
A prototype for a function which takes a function parameter looks like the following:
void func ( void (*f)(int) );
This states that the parameter f will be a pointer to a function which has a void return type and which takes a single int parameter. The following function (print) is an example of a function which could be passed to func as a parameter because it is the proper type:
void print ( int x ) {
printf("%d\n", x);
}
Function Call
When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this:
func(print);
would call func, passing the print function to it.
Function Body
As with any parameter, func can now use the parameter's name in the function body to access the value of the parameter. Let's say that func will apply the function it is passed to the numbers 0-4. Consider, first, what the loop would look like to call print directly:
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
Since func's parameter declaration says that f is the name for a pointer to the desired function, we recall first that if f is a pointer then *f is the thing that f points to (i.e. the function print in this case). As a result, just replace every occurrence of print in the loop above with *f:
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
Source
This question already has the answer for defining function pointers, however they can get very messy, especially if you are going to be passing them around your application. To avoid this unpleasantness I would recommend that you typedef the function pointer into something more readable. For example.
typedef void (*functiontype)();
Declares a function that returns void and takes no arguments. To create a function pointer to this type you can now do:
void dosomething() { }
functiontype func = &dosomething;
func();
For a function that returns an int and takes a char you would do
typedef int (*functiontype2)(char);
and to use it
int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');
There are libraries that can help with turning function pointers into nice readable types. The boost function library is great and is well worth the effort!
boost::function<int (char a)> functiontype2;
is so much nicer than the above.
Since C++11 you can use the functional library to do this in a succinct and generic fashion. The syntax is, e.g.,
std::function<bool (int)>
where bool is the return type here of a one-argument function whose first argument is of type int.
I have included an example program below:
// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Sometimes, though, it is more convenient to use a template function:
// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Pass address of a function as parameter to another function as shown below
#include <stdio.h>
void print();
void execute(void());
int main()
{
execute(print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void f()) // receive address of print
{
f();
}
Also we can pass function as parameter using function pointer
#include <stdio.h>
void print();
void execute(void (*f)());
int main()
{
execute(&print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void (*f)()) // receive address of print
{
f();
}
Functions can be "passed" as function pointers, as per ISO C11 6.7.6.3p8: "A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1. ". For example, this:
void foo(int bar(int, int));
is equivalent to this:
void foo(int (*bar)(int, int));
I am gonna explain with a simple example code which takes a compare function as parameter to another sorting function.
Lets say I have a bubble sort function that takes a custom compare function and uses it instead of a fixed if statement.
Compare Function
bool compare(int a, int b) {
return a > b;
}
Now , the Bubble sort that takes another function as its parameter to perform comparison
Bubble sort function
void bubble_sort(int arr[], int n, bool (&cmp)(int a, int b)) {
for (int i = 0;i < n - 1;i++) {
for (int j = 0;j < (n - 1 - i);j++) {
if (cmp(arr[j], arr[j + 1])) {
swap(arr[j], arr[j + 1]);
}
}
}
}
Finally , the main which calls the Bubble sort function by passing the boolean compare function as argument.
int main()
{
int i, n = 10, key = 11;
int arr[10] = { 20, 22, 18, 8, 12, 3, 6, 12, 11, 15 };
bubble_sort(arr, n, compare);
cout<<"Sorted Order"<<endl;
for (int i = 0;i < n;i++) {
cout << arr[i] << " ";
}
}
Output:
Sorted Order
3 6 8 11 12 12 15 18 20 22
You need to pass a function pointer. The syntax is a little cumbersome, but it's really powerful once you get familiar with it.
typedef int function();
function *g(function *f)
{
f();
return f;
}
int main(void)
{
function f;
function *fn = g(f);
fn();
}
int f() { return 0; }
It's not really a function, but it is an localised piece of code. Of course it doesn't pass the code just the result. It won't work if passed to an event dispatcher to be run at a later time (as the result is calculated now and not when the event occurs). But it does localise your code into one place if that is all you are trying to do.
#include <stdio.h>
int IncMultInt(int a, int b)
{
a++;
return a * b;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 7;
printf("%d * %d = %d\n", a, b, IncMultInt(a, b));
b = 9;
// Create some local code with it's own local variable
printf("%d * %d = %d\n", a, b, ( { int _a = a+1; _a * b; } ) );
return 0;
}

How to modify a local variable of one function from other function?

int main ()
{
int a, b;
call(&b);
printf("%d, %d",a , b);
}
void call(int *ptr)
{
}
Desired output:
50, 100
How to write the call function so as to modify both the variables to get the desired output??
Not sure where the values 50 and 100 are coming from or exactly what you are asking but maybe this will help with your question.
Since C is pass by value you need to send pointers to actually change the value inside another function.
Since the call function will have pointer values you need to dereference the pointers before changing the value.
Here is an example:
void call(int *a, int *b)
{
*a = 50;
*b = 100;
}
int main()
{
int a, b;
call(&a, &b);
printf("%d, %d\n", a, b);
}
While we are exploring the many ways this output could be achieved, consider that the function could store state in a static variable:
#include <stdio.h>
void call(int *ptr);
int main(void)
{
int a, b;
call(&a);
call(&b);
printf("%d, %d\n",a , b);
}
void call(int *ptr)
{
static int store = 0;
store += 50;
*ptr = store;
}
Program output:
50, 100
Note that you may also be able to do this as follows, without any modifications to main(). But be warned that this method invokes undefined behavior! It is undefined behavior to write to a location past the end of an array object, and in the case of a and b, these are considered to be array objects of size 1. Here we are assuming that this write will work, and that a and b are stored next to each other in memory. We further assume that a has the higher address in memory.
I would say that you should never do this, but I can see no other way to modify a from the function call() without knowing the address of a. You have been warned.
void call(int *ptr)
{
*ptr = 100;
*(ptr + 1) = 50;
}
Try something like this:
void call(int *ptr)
{
*ptr = 100;
}
int main ()
{
int a, b;
a = 50;
call(&b);
printf("%d, %d",a , b);
}
See demo
Maybe you want this:
int main ()
{
int a, b;
call(&a, &b);
printf("%d, %d",a , b);
}
void call(int *ptr1, int *ptr2)
{
*a = 50;
*b = 100;
}
To change a local variable in function a by calling function b you have two options.
1) Let function b return a value that you assign to the variable in function a. Like:
int b() {return 42;}
void a()
{
int x = b();
printf("%d\n", x);
}
This does, however, not seem to be what you are looking for.
2) Pass a pointer to the variable to function b and change the variable through that pointer
void b(int* p) // Notice the * which means the function takes a pointer
// to integer as argument
{
*p = 42; // Notice the * which means that 42 is assigned to the variable
// that p points to
}
void a()
{
int x;
b(&x); // Notice the & which means "address of x" and thereby
// becomes a pointer to the integer x
printf("%d\n", x);
}
int main()
{
int a,b;
call(&b);
printf("%d, %d\n", a,b);
}
int call(int *ptr)
{
int *m;
m = ptr++;
*ptr = 50;
*m = 100;
}

C multiple types function

I'd like to write some functions in C but they have to be available for all numeric types (int, float, double). What is good practise? Use pointer on void (and pointer to function of course)? Or write a different function for every type?
For example:
float func(float a, float b) {
return a+b;
}
If you can use C11, _Generic can help:
#include <stdio.h>
int ifunc(int a, int b) { return a+b; }
float ffunc(float a, float b) { return a+b; }
double dfunc(double a, double b) { return a+b; }
#define func(x, y) \
_Generic((x), int: ifunc, float: ffunc, double: dfunc, default: ifunc)(x, y)
int main(void)
{
{
int a = 1, b = 2, c;
c = func(a, b);
printf("%d\n", c);
}
{
float a = .1f, b = .2f, c;
c = func(a, b);
printf("%f\n", c);
}
{
double a = .1, b = .2, c;
c = func(a, b);
printf("%f\n", c);
}
return 0;
}
As C does not have multiple dispatch (function overloading) like C++ (EDIT: unless you use C11, which has _Generic) , you have to name the functions for each type differently, like funcInt(int a, int b); funcFloat(float a, float b);
OR
use GCC style statement-expression macros which allow typeof() to kind of fake it.
The old style C way is to use a union and a discriminator:
union multi_num {
uint32_t small_num;
uint64_t large_num;
float float_num;
};
struct multi_type {
int discriminator;
union multi_num val;
};
int
add_fun (struct multi_type var1, struct multi_type var2, struct multi_type *ret_val)
{
if (var1.discriminator != var2.discriminator) {
return -1;
}
ret_val->discriminator = var1.discriminator;
switch (var1.discriminator) {
case 1:
ret_val->val.small_num = var1.val.small_num + var2.val.small_num;
break;
case 2:
ret_val->val.large_num = var1.val.large_num + var2.val.large_num;
break;
case 3:
ret_val->val.float_num = var1.val.float_num + var2.val.float_num;
break;
}
return 0;
}
Then you can call it like this:
struct multi_type var1, var2, var3 = {0};
var1.discriminator = 1;
var2.discriminator = 1;
var1.val.small_num = 1;
var2.val.small_num = 12;
ret = add_fun(var1, var2, &var3);
if (0 == ret) {
printf("add worked, ret is %d\n", var3.val.small_num);
} else {
printf("add failed\n");
}
In C++, this would have easily been done with templates or function overloading.
The only way I know in C is to write a different function for every type.
You can use a function taking two void* and compute with them, but it's extremely misleading for the user: what if there is a special type for which another version of the function is available but the user uses the void* function? This can lead to big problems, and is not recommended.
For a practical example of this, look at the standard string conversion functions atoi, atol, atof located in stdlib.h. One function per variable type.

Function Pointer in C

How can I create a "function pointer" (and (for example) the function has parameters) in C?
http://www.newty.de/fpt/index.html
typedef int (*MathFunc)(int, int);
int Add (int a, int b) {
printf ("Add %d %d\n", a, b);
return a + b; }
int Subtract (int a, int b) {
printf ("Subtract %d %d\n", a, b);
return a - b; }
int Perform (int a, int b, MathFunc f) {
return f (a, b); }
int main() {
printf ("(10 + 2) - 6 = %d\n",
Perform (Perform(10, 2, Add), 6, Subtract));
return 0; }
typedef int (*funcptr)(int a, float b);
funcptr x = some_func;
int a = 3;
float b = 4.3;
x(a, b);
I found this site helpful when I was first diving into function pointers.
http://www.newty.de/fpt/index.html
First declare a function pointer:
typedef int (*Pfunct)(int x, int y);
Almost the same as a function prototype.
But now all you've created is a type of function pointer (with typedef).
So now you create a function pointer of that type:
Pfunct myFunction;
Pfunct myFunction2;
Now assign function addresses to those, and you can use them like they're functions:
int add(int a, int b){
return a + b;
}
int subtract(int a, int b){
return a - b;
}
. . .
myFunction = add;
myFunction2 = subtract;
. . .
int a = 4;
int b = 6;
printf("%d\n", myFunction(a, myFunction2(b, a)));
Function pointers are great fun.
You can also define functions that return pointers to functions:
int (*f(int x))(double y);
f is a function that takes a single int parameter and returns a pointer to a function that takes a double parameter and returns int.

How do you pass a function as a parameter in C?

I want to create a function that performs a function passed by parameter on a set of data. How do you pass a function as a parameter in C?
Declaration
A prototype for a function which takes a function parameter looks like the following:
void func ( void (*f)(int) );
This states that the parameter f will be a pointer to a function which has a void return type and which takes a single int parameter. The following function (print) is an example of a function which could be passed to func as a parameter because it is the proper type:
void print ( int x ) {
printf("%d\n", x);
}
Function Call
When calling a function with a function parameter, the value passed must be a pointer to a function. Use the function's name (without parentheses) for this:
func(print);
would call func, passing the print function to it.
Function Body
As with any parameter, func can now use the parameter's name in the function body to access the value of the parameter. Let's say that func will apply the function it is passed to the numbers 0-4. Consider, first, what the loop would look like to call print directly:
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
Since func's parameter declaration says that f is the name for a pointer to the desired function, we recall first that if f is a pointer then *f is the thing that f points to (i.e. the function print in this case). As a result, just replace every occurrence of print in the loop above with *f:
void func ( void (*f)(int) ) {
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
(*f)(ctr);
}
}
Source
This question already has the answer for defining function pointers, however they can get very messy, especially if you are going to be passing them around your application. To avoid this unpleasantness I would recommend that you typedef the function pointer into something more readable. For example.
typedef void (*functiontype)();
Declares a function that returns void and takes no arguments. To create a function pointer to this type you can now do:
void dosomething() { }
functiontype func = &dosomething;
func();
For a function that returns an int and takes a char you would do
typedef int (*functiontype2)(char);
and to use it
int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');
There are libraries that can help with turning function pointers into nice readable types. The boost function library is great and is well worth the effort!
boost::function<int (char a)> functiontype2;
is so much nicer than the above.
Since C++11 you can use the functional library to do this in a succinct and generic fashion. The syntax is, e.g.,
std::function<bool (int)>
where bool is the return type here of a one-argument function whose first argument is of type int.
I have included an example program below:
// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Sometimes, though, it is more convenient to use a template function:
// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
return func(a,b);
}
double Add(double a, double b){
return a+b;
}
double Mult(double a, double b){
return a*b;
}
int main(){
Combiner(12,13,Add);
Combiner(12,13,Mult);
}
Pass address of a function as parameter to another function as shown below
#include <stdio.h>
void print();
void execute(void());
int main()
{
execute(print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void f()) // receive address of print
{
f();
}
Also we can pass function as parameter using function pointer
#include <stdio.h>
void print();
void execute(void (*f)());
int main()
{
execute(&print); // sends address of print
return 0;
}
void print()
{
printf("Hello!");
}
void execute(void (*f)()) // receive address of print
{
f();
}
Functions can be "passed" as function pointers, as per ISO C11 6.7.6.3p8: "A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1. ". For example, this:
void foo(int bar(int, int));
is equivalent to this:
void foo(int (*bar)(int, int));
I am gonna explain with a simple example code which takes a compare function as parameter to another sorting function.
Lets say I have a bubble sort function that takes a custom compare function and uses it instead of a fixed if statement.
Compare Function
bool compare(int a, int b) {
return a > b;
}
Now , the Bubble sort that takes another function as its parameter to perform comparison
Bubble sort function
void bubble_sort(int arr[], int n, bool (&cmp)(int a, int b)) {
for (int i = 0;i < n - 1;i++) {
for (int j = 0;j < (n - 1 - i);j++) {
if (cmp(arr[j], arr[j + 1])) {
swap(arr[j], arr[j + 1]);
}
}
}
}
Finally , the main which calls the Bubble sort function by passing the boolean compare function as argument.
int main()
{
int i, n = 10, key = 11;
int arr[10] = { 20, 22, 18, 8, 12, 3, 6, 12, 11, 15 };
bubble_sort(arr, n, compare);
cout<<"Sorted Order"<<endl;
for (int i = 0;i < n;i++) {
cout << arr[i] << " ";
}
}
Output:
Sorted Order
3 6 8 11 12 12 15 18 20 22
You need to pass a function pointer. The syntax is a little cumbersome, but it's really powerful once you get familiar with it.
typedef int function();
function *g(function *f)
{
f();
return f;
}
int main(void)
{
function f;
function *fn = g(f);
fn();
}
int f() { return 0; }
It's not really a function, but it is an localised piece of code. Of course it doesn't pass the code just the result. It won't work if passed to an event dispatcher to be run at a later time (as the result is calculated now and not when the event occurs). But it does localise your code into one place if that is all you are trying to do.
#include <stdio.h>
int IncMultInt(int a, int b)
{
a++;
return a * b;
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 7;
printf("%d * %d = %d\n", a, b, IncMultInt(a, b));
b = 9;
// Create some local code with it's own local variable
printf("%d * %d = %d\n", a, b, ( { int _a = a+1; _a * b; } ) );
return 0;
}

Resources