I must be doing something monumentally stupid here but I can’t figure out what. If I printf the values within the foo function, it displays the correct values.
But if I try to print them in main, I get nonsense results (0 and 1, respectively).
void foo(int a, int b){
a = 1;
b = 2;
}
int main(void){
int a;
int b;
foo(a, b);
printf(“%i \n”, a);
printf(“%i \n”, b);
}
You need to change your foo method to take pointers:
void foo(int *a, int *b)
{
*a = 1;
*b = 2;
}
Then your call to foo must change to:
foo(&a, &b);
This basically says: Pass the address of 'a' and 'b' to the function foo, so it has the ability to change their values.
Your previous code just sent a copy of 'a' and 'b' into foo, so the change made in foo had no effect on your original two variables.
In your program you are trying to change the local variables in your function without passing their adresses.It may give you error in your code.If you pass the addresses to the function you can change the values of variables.
foo(&a, &b);//Passing addresses to the function.
void foo(int *a, int *b)//accessing value at that address
The above process is called 'call by reference'.
Related
In the code, I omitted parameters for int (*bar) and assigned &foo, which as 3 arguments, to bar. (*bar) received the numbers and gave me a return value. I thought this is ok but I've heard that this is actually UB. How does (*bar) receive the numbers? Thx
#include <stdio.h>
int foo(int a, int b, int c){
return a+b+c;
}
int main(void) {
int (*bar)() = &foo;
printf("%d", bar(1, 2, 3));
return 0;
}
edit
When I pass more than three arguments to bar() (say 5 arguments), the program works. Where do the two extra arguments go?
What does the C standard have to say regarding typedef-ed function pointers being const qualified in parameters to functions? For example, say I have the following type
typedef int (*Operation)(int a, int b);
I've got a bunch of operations which take two ints, performs the operation, and then returns an int. Then I have a function which performs the actual function pointer call.
int doOpOnce(const Operation op, int a, int b)
{
return op(a, b);
}
I want to guarantee that the function pointer doesn't change during the doOpOnce call and I also want to document to users of doOpOnce that it will actually call the function given to it. Is this valid? Is there any difference between:
int doOpOnce(const Operation op, int a, int b)
int doOpOnce(Operation const op, int a, int b)
Finally, here is an example. Its compiled with gcc 4.9.2 with flags -std=c99 -Wall -Wextra -pedantic and it correctly errors when I try to change my const function pointer.
#include <stdio.h>
typedef int (*Operation)(int a, int b);
int opAdd(int a, int b)
{
return a + b;
}
int opSub(int a, int b)
{
return a - b;
}
int doOpOnce(const Operation op, int a, int b)
{
op = opSub; // error: assignment of read-only parameter 'op'
return op(a, b);
}
int main()
{
printf("%d\n", doOpOnce(opAdd, 10, 20));
return 0;
}
I do not want to add the const qualifier to the Operation typedef as I have other functions which CAN modify Operation pointers. I just want stronger typing in some circumstances.
If the parameter type is Operation, the caller passes a copy of the pointer into the function and so the function can't actually change where that pointer is pointing back in the caller. Adding the const keyword here would just be a defensive technique in the implementation that prevents you from reassigning your local copy. In that sense, you probably don't even need the const qualifier to signal anything to the client of your library.
To address your other question, the two placements of const have the same meaning, so you can pick whichever one you'd like.
Let the outside world (.h) see int doOpOnce(Operation op, int a, int b); and your .c file implement int doOpOnce(Operation const op, int a, int b) { so "to guarantee that the function pointer doesn't change during the doOpOnce"
"I also want to document to users of doOpOnce that it will actually call the function given to it. " belongs in the code documentation.
A function declaration signature of int doOpOnce(Operation const op, int a, int b); is not sufficient to guarantee "it will actually call the function given to it".
For the user of the function doOpOnce it is unimportant whether the pointer to function declared with the const qualifier or not because the function deals with a copy of the original pointer supplied by the user as an argument.
For the user of the function these two function declarations
int doOpOnce(const Operation op, int a, int b);
and
int doOpOnce( Operation op, int a, int b);
declare the same one function. You may include the both declarations in the program.
It is only within the function definition you will not be able to change this pointer that is a local variable of the function as any its parameter.
.
I'm new to programming and I am currently working on C.
I learned that C does not have call by reference. The programs that we write to pass the address of actual parameters to the formal parameters is also call by Value in C.
Correct me if I'm wrong.. However, I ran this program :
//Swapping of two numbers using functions.
#include
void swap(int *,int *);
void main()
{
int x,y;
printf ("Enter the values of x and y : ");
scanf("%d %d",&x,&y);
swap(x,y);
printf("The value of x = %d and y = %d",x,y);
}
void swap(int *a,int *b)
{
int temp;
temp=*b;
*b=*a;
*a=temp;
}
It compiles just fine.. however, I'm getting a Segmentation Fault in the Output.
It asks me the enter the value of X and Y and then gives, Segmentation fault..
Please help!!
you are sending an int to a function that expects int*, thus when you are dereferencing - temp=*b; you are trying to access memory you don't own -> segfault. Call swap like this: swap(&x,&y);
So close
swap(&x,&y);
You were not passing references (pointers)
To avoid similar segfaults at runtime, always compile with -Wall.
Actually, there is a way to pass-by-reference in C, just change two lines in your code like this:
#define swap(x,y) swap_impl__(&(x), &(y))
static void swap_impl__(int *a, int *b)
{
int temp;
temp=*b;
*b=*a;
*a=temp;
}
void main()
{
int x,y;
printf ("Enter the values of x and y : ");
scanf("%d %d",&x,&y);
swap(x,y);
printf("The value of x = %d and y = %d",x,y);
}
the call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.
but here you are passing values
swap(x,y)
but taking it as address
void swap(int *a,int *b)
so it is looking for an address which passed by your variable.
for example, if you have passed something like
swap(x,y)
and
if we have x=100 and y=200, then it is assuming 100 and 200 to be addresses
and trying to access it will definitely give you error as they may not exist or having garbage value.
im trying to make a procedure to find a maximum numbers out of 3, which i will assign later to another variable pointer in main program
int Maximum (int *a, int *b, int *c)
{
if (*a>=*b)
{
if (*a<*c)
{*a=*c;}
}
else
{
*a=*b;
if (*a<*c)
{*a=*c;}
}
return a;
}
compiler giving me error that "expected 'int*' but argument is of type 'int' "
so i changes that part to
int * Maximum (int *a, int *b, int *c)
but error sentence still same ?
First off, your original function is designed to return an int and you're returning a, which is an int pointer. Either return the int (*a), or change the function so it returns an int *.
However, based on your actual message:
expected 'int*' but argument is of type 'int'
and the fact you state you've made that change and still have the problem (note the word "argument" in the message), this indicates that the problem lies not with the return value but with the way you're passing the arguments to it.
You are actually passing int where the function expects int * and that's probably caused by you using something like:
int one = 3;
int two = 7;
int three = 42;
int maxOfThree = Maximum (one, two, three);
If you wanted to pass pointers to the function, you would need:
Maximum (&one, &two, &three);
(passing the pointers to the variables, not the values of them).
A better solution (more readable and with correct data types both going in to, and coming out of, the function) to your problem would probably be:
int Maximum (int a, int b, int c) {
if ((a > b) && (a > c))
return a;
if (b > c)
return b;
return c;
}
As the title says, how do I use the pointer of a function in C? Can I just take the address of the function name and pass it to another function; then dereference it and call it?
Thanks a lot.
If you know the function address, then yes. For example:
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int operation(int (*op)(int, int), int a, int b)
{
return op(a, b);
}
Then just call it like this:
printf("%d\n", operation(&add, 5, 3)); // 8
printf("%d\n", operation(&sub, 5, 3)); // 2
You can even do some array tricks:
int op = 0;
int (*my_pointer[2])(int, int) =
{
add, // op = 0 for add
sub // op = 1 for sub
};
printf("%d\n", my_pointer[op](8, 2)); // 10
well to answer your question precisely, there is a provision in C for such needs which is called "function pointer".
But you have to follow certain rules,
1) All the functions you want to call using function pointer must have same return type.
2) All the functions you want to call using function pointer must have same no of arguments and argument types.
For example,
int add(int, int);
int sub(int, int);
for above two functions you can write function pointer as,
int (*operation)(int , int);
and you can use it just as described by Flavio Torbio.
hope it helps.....