error compilation, function pointer - c

i have a simple program like this :
#include<stdio.h>
void add(int *nb)
{
*nb += 1;
}
int f(int nb, void (*add)(int *))
{
if (nb < 5)
f(nb, add(&nb));
return (nb);
}
int main() {
int b = 5;
int a = f(b, add);
printf("%d\n", a);
}
i want to call f recursively until nb become greater or equal to 5, but when i compile the program , the gcc compiler show something like this :
error: passing 'void' to parameter of incompatible type 'void (*)(int *)'
can anyone help me please?

I'm not completely certain as to what you are trying to do with your function, but I took a stab at what I think you might be attempting to do:
#include<stdio.h>
void add(int *nb)
{
*nb += 1;
}
int f(int nb, void (*function)(int *))
{
function(&nb);
if (nb < 5)
f(nb, function);
return (nb);
}
int main() {
int b = 5;
int a = f(b, add);
printf("%d\n", a);
}
Now your function f accepts a function-pointer to a void function that takes an int * as an argument (I renamed this argument to function so it doesn't conflict with your existing function add). It proceeds to call said function and pass in a pointer to nb to function.
What you were doing was passing in the result of add(&nb) into the function f as an argument (which said function is a void so it does not return anything) instead of passing in a pointer to the function.

The line f(nb, add(&nb)); doesn't make sense. You need to call the function somewhere, but not on the same line as where you pass the function pointer on, recursively.
Overall the program doesn't make much sense. I have no idea what you are trying to do, perhaps something similar to this?
#include<stdio.h>
void add(int *nb)
{
*nb += 1;
}
void f(int* nb, void (*add)(int *))
{
add(nb);
if (*nb < 5)
{
f(nb, add);
}
}
int main() {
int a = 5;
f(&a, add);
printf("%d\n", a);
}
Will print 6 since the add is called once. The name add as function parameter to f is also mighty confusing, so better come up with another name for it.

Passing add(&nb) as an argument passes the returned value of add with the argument &nb. The function signature for f requires a function pointer, which can be passed as:
f(nb, add)
Also, even if you were actually trying to pass the returned value of add, that would be undefined behavior since it is of type void.

As Christian pointed out in the comments, the problem is on the recursive call line:
f(nb, add(&nb));
If I understand correctly you are trying to increase nb using the function you receive as a pointer; here however you first pass nb unchanged (and as a value, not by reference), and then call the add function.
In the second argument the compiler is expecting a function pointer, but instead it receives the return value of the add(&nb) function call, which is void.
Also, in case nb is < 5 you need to return the recursive call.
The correct procedure would be:
#include<stdio.h>
void add(int *nb)
{
*nb += 1;
}
int f(int nb, void (*add)(int *))
{
if (nb < 5) {
add(&nb);
return f(nb, add);
}
return (nb);
}
int main() {
int b = 1;
int a = f(b, add);
printf("%d\n", a);
}
It almost seems like you're trying to use lazy evaluation, but C doesn't have that!

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;
}

Error: Semantic issue Assigning to 'int' from incompatible type 'void'

While creating a program with function prototype, a problem has occurred. It said:
Semantic issue Assigning to 'int' from incompatible type 'void'.
Could you please help me resolve this issue?
Here is my code:
#include <stdio.h>
#include <math.h>
void powr(int);
int main(void) {
int n=1, sq, cu, quart, quint;
printf("Integer Square Cube Quartic Quintic\n");
do {
sq = powr(n); //here is the error line
cu = powr(n); //here is the error line
quart = powr(n); //here is the error line
quint = powr(n); //here is the error line
printf("%d %d %d %d %d\n", n, sq, cu, quart, quint);
n++;
}
while (n<=25);
return 0;
}
void powr(int n)
{
int a, cu, quart, quint;
a=pow(n,2);
cu=pow(n,3);
quart=pow(n,4);
quint=pow(n,2);
}
void powr(int n)
means that the function will return nothing, so you're not allowed to do something like:
sq = powr(n);
If you want your function to take an int and return an int, it should be:
int powr(int n)
(for both the prototype and the function definition).
In any case, variables that you set within the powr function are not available to the caller (and using globals is a very bad idea in general), so you'd need to either change the function to return just the square of the number and call it thus:
sq = powr (n);
cu = n * sq;
quart = powr (sq);
quint = n * quart;
Or you could pass the addresses of the variables into the function so they could be changed, something like:
void powr(int n, int *pSq, int *pCu, int *pTo4, int *pTo5) {
*pSq = pow (n, 2);
*pCu = *pSq * n;
*pTo4 = pow (*pSq, 2);
*pTo5 = *pCu * *pSq;
}
and call it with:
powr (n, &sq, &cu, &quart, &quint);
I would suggest using the former approach, given the level you appear to be learning at (no offence intended, just stating that to assist you in selecting the appropriate method).

'*' around parentheses : pointers

Consider this code for qsort:
#include <stdio.h>
#include <stdlib.h>
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc(const void * a, const void * b)
{
return *(int*)a - *(int*)b;
}
int main()
{
int n;
printf("Before sorting the list is: \n");
for (n = 0; n < 5; n++)
{
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for (n = 0; n < 5; n++)
{
printf("%d ", values[n]);
}
return(0);
}
what does *(int*)a means specifically? It looks like a pointer to a pointer? why cant i do:
**a // dereferrencing twice would get the value, no?
or
*(int *a) // looks about the same. Also why do i need the int?
apologies if this question seemed obvious as I've been looking at this for hours now, and i still cant grasp why that '*' is wrapping around the bracket.
void* and const void* are used in C to stand in for a generic pointer of unknown type. qsort doesn't really know what it's sorting: the callback comparison function cmpfunc does that task. But C is statically-typed, so the callback function needs to have a specific prototype. That's where const void* is useful.
Of course, within your supplied cmpfunc, you know the type of object being sorted, so you are able to cast the const void* to your type. That is what (int*) is doing: it's a cast.
Technically you should cast to const int* instead:
return *(const int*)a - *(const int*)b;
Casting away const can cause you trouble.
A pointer to void can't be dereferenced. Therefore, in the given case it must have to cast to int * before dereferencing.
In *(int*)a, (int*) is casting a to pointer to int and then * outside the parenthesis dereferencing the value at that address.

C pass int array pointer as parameter into a function

I want to pass the B int array pointer into func function and be able to change it from there and then view the changes in main function
#include <stdio.h>
int func(int *B[10]){
}
int main(void){
int *B[10];
func(&B);
return 0;
}
the above code gives me some errors:
In function 'main':|
warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default]|
note: expected 'int **' but argument is of type 'int * (*)[10]'|
EDIT:
new code:
#include <stdio.h>
int func(int *B){
*B[0] = 5;
}
int main(void){
int B[10] = {NULL};
printf("b[0] = %d\n\n", B[0]);
func(B);
printf("b[0] = %d\n\n", B[0]);
return 0;
}
now i get these errors:
||In function 'func':|
|4|error: invalid type argument of unary '*' (have 'int')|
||In function 'main':|
|9|warning: initialization makes integer from pointer without a cast [enabled by default]|
|9|warning: (near initialization for 'B[0]') [enabled by default]|
||=== Build finished: 1 errors, 2 warnings ===|
In your new code,
int func(int *B){
*B[0] = 5;
}
B is a pointer to int, thus B[0] is an int, and you can't dereference an int. Just remove the *,
int func(int *B){
B[0] = 5;
}
and it works.
In the initialisation
int B[10] = {NULL};
you are initialising anint with a void* (NULL). Since there is a valid conversion from void* to int, that works, but it is not quite kosher, because the conversion is implementation defined, and usually indicates a mistake by the programmer, hence the compiler warns about it.
int B[10] = {0};
is the proper way to 0-initialise an int[10].
Maybe you were trying to do this?
#include <stdio.h>
int func(int * B){
/* B + OFFSET = 5 () You are pointing to the same region as B[OFFSET] */
*(B + 2) = 5;
}
int main(void) {
int B[10];
func(B);
/* Let's say you edited only 2 and you want to show it. */
printf("b[0] = %d\n\n", B[2]);
return 0;
}
If you actually want to pass an array pointer, it's
#include <stdio.h>
void func(int (*B)[10]){ // ptr to array of 10 ints.
(*B)[0] = 5; // note, *B[0] means *(B[0])
//B[0][0] = 5; // same, but could be misleading here; see below.
}
int main(void){
int B[10] = {0}; // not NULL, which is for pointers.
printf("b[0] = %d\n\n", B[0]);
func(&B); // &B is ptr to arry of 10 ints.
printf("b[0] = %d\n\n", B[0]);
return 0;
}
But as mentioned in other answers, it's not that common to do this. Usually a pointer-to-array is passed only when you want to pass a 2d array, where it suddenly looks a lot clearer, as below. A 2D array is actually passed as a pointer to its first row.
void func( int B[5][10] ) // this func is actually the same as the one above!
{
B[0][0] = 5;
}
int main(void){
int Ar2D[5][10];
func(Ar2D); // same as func( &Ar2D[0] )
}
The parameter of func may be declared as int B[5][10], int B[][10], int (*B)[10], all are equivalent as parameter types.
Addendum: you can return a pointer-to-array from a function, but the syntax to declare the function is very awkward, the [10] part of the type has to go after the parameter list:
int MyArr[5][10];
int MyRow[10];
int (*select_myarr_row( int i ))[10] { // yes, really
return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}
This is usually done as below, to avoid eyestrain:
typedef int (*pa10int)[10];
pa10int select_myarr_row( int i ) {
return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}
In new code assignment should be,
B[0] = 5
In func(B), you are just passing address of the pointer which is pointing to array B. You can do change in func() as B[i] or *(B + i). Where i is the index of the array.
In the first code the declaration says,
int *B[10]
says that B is an array of 10 elements, each element of which is a pointer to a int. That is, B[i] is a int pointer and *B[i] is the integer it points to the first integer of the i-th saved text line.
Make use of *(B) instead of *B[0].
Here, *(B+i) implies B[i] and *(B) implies B[0], that is *(B+0)=*(B)=B[0].
#include <stdio.h>
int func(int *B){
*B = 5;
// if you want to modify ith index element in the array just do *(B+i)=<value>
}
int main(void){
int B[10] = {};
printf("b[0] = %d\n\n", B[0]);
func(B);
printf("b[0] = %d\n\n", B[0]);
return 0;
}
main()
{
int *arr[5];
int i=31, j=5, k=19, l=71, m;
arr[0]=&i;
arr[1]=&j;
arr[2]=&k;
arr[3]=&l;
arr[4]=&m;
for(m=0; m<=4; m++)
{
printf("%d",*(arr[m]));
}
return 0;
}
Using the really excellent example from Greggo, I got this to work as a bubble sort with passing an array as a pointer and doing a simple -1 manipulation.
#include<stdio.h>
void sub_one(int (*arr)[7])
{
int i;
for(i=0;i<7;i++)
{
(*arr)[i] -= 1 ; // subtract 1 from each point
printf("%i\n", (*arr)[i]);
}
}
int main()
{
int a[]= { 180, 185, 190, 175, 200, 180, 181};
int pos, j, i;
int n=7;
int temp;
for (pos =0; pos < 7; pos ++){
printf("\nPosition=%i Value=%i", pos, a[pos]);
}
for(i=1;i<=n-1;i++){
temp=a[i];
j=i-1;
while((temp<a[j])&&(j>=0)) // while selected # less than a[j] and not j isn't 0
{
a[j+1]=a[j]; //moves element forward
j=j-1;
}
a[j+1]=temp; //insert element in proper place
}
printf("\nSorted list is as follows:\n");
for(i=0;i<n;i++)
{
printf("%d\n",a[i]);
}
printf("\nmedian = %d\n", a[3]);
sub_one(&a);
return 0;
}
I need to read up on how to encapsulate pointers because that threw me off.
The argument of func is accepting double-pointer variable.
Hope this helps...
#include <stdio.h>
int func(int **B){
}
int main(void){
int *B[10];
func(B);
return 0;
}
In the function declaration you have to type as
VOID FUN(INT *a[]);
/*HERE YOU CAN TAKE ANY FUNCTION RETURN TYPE HERE I CAN TAKE VOID AS THE FUNCTION RETURN TYPE FOR THE FUNCTION FUN*/
//IN THE FUNCTION HEADER WE CAN WRITE AS FOLLOWS
void fun(int *a[])
//in the function body we can use as
a[i]=var

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