Returning a pointer to a function in C syntax - c

In one of the answer to How do function pointers in C work? one user explains how to use function pointers in return values. Here's the code in question:
// this is a function called functionFactory which receives parameter n
// and returns a pointer to another function which receives two ints
// and it returns another int
int (*functionFactory(int n))(int, int) {
printf("Got parameter %d", n);
int (*functionPtr)(int,int) = &addInt;
return functionPtr;
}
For me the way you declare the functionFactory function is very weird - it seems to me that you mix up the return type (pointer to a function) and the function name itself (functionFactory).
For example, when we write a simple function that returns a square of its argument we write something like
int square(int n){
return n*n;
}
Clearly, the type of what we return is on the left and then we write the function name and then what parameters it accepts. So when we return a pointer to a function why don't we write something like:
( int (*function)(int, int) ) functionFactory(int n) { ...
Here the return type (which is a pointer to a function) and its details (e.g. what the function that we point to returns and what it accepts as parameters) is clearly on the left separated and the name of the functionFactory function itself is to the right. To me my version seems much more logical and clear, why don't we write it like that?

This falls out of how declarator syntax works. It may help to think in terms of substitution. Here's one way to look it:
T f (); // f is a function returning T
|
v
T (*p) (); // p is a pointer to a function returning T
|
v
T (*q())(); // q is a function returning a pointer to a function returning T
So we start with the function declarator f(). Then we replace f with the pointer (*p), giving us the declarator (*p)(). Finally we replace p with the function q(), giving us the declarator (*q())().
Edit
You may hear people talk about the "spiral rule" when reading hairy declarators. While it's more of a guideline than an actual rule, it falls out of the following precedence rules:
T *a[N]; // a is an array of pointer to T
T (*a)[N]; // a is a pointer to an array of T
T *f(); // f is a function returning T
T (*f)(); // f is a pointer to a function returning T
The postfix [] and () operators have higher precedence than unary *, hence the need for parentheses when declaring pointers to arrays or functions. So when we read T (*q())();, we start from the leftmost identifier q and "spiral" outwards:
+-----------+
| +-------+ |
| | +---+ | |
| | | | | |
T ( * q ()) ()
| | | | | |
| | +-+ | |
| +-----+ |
+---------+
Breaking it down piece by piece:
q -- q is a
q() -- function returning
*q() -- pointer to
(*q())() -- function returning
T (*q())(); -- T
You cannot declare arrays of function type, nor can you declare functions to return array types:
T a[N](); // NOT ALLOWED
T f()[N]; // NOT ALLOWED
so in any combination of function and array types, a pointer will always be involved, so the spiral rule holds.

The following code declares a variable named func to be a pointer to a function that returns an int and takes two ints as parameters:
int (*func)(int, int);
This syntax mimics the syntax how functions are declared in C:
int func(int, int);
See how similar that is? In fact functions in C are just like variables pointing to functions, e.g. see this sample:
int funcA(int a, int b) { ... }
int (*funcB)(int, int) = funcA;
It plays no role through the rest of the code if you call funcA(a,b) or funcB(a,b), does it? So even though funcB is a variable and funcA a function, the truth is, there's a function somewhere in memory and funcA and funcB are both pointers to the address of the function code.
If you want to nitpick, funcA is a constant and funcB is a variable, so the compiler output for a call to funcA will be different than for funcB; also in one case it is a direct call and in one case an indirect call, as the destination of funcB can change over time. This is also what the asterisk is saying, "I'm not a function, I'm a pointer to a function".
It's important to note that in C the asterisk is always next to the variable name to mark that a pointer variable, so how else would you like to write it instead? Like this?
// Careful! Wrong!
int (int, int) *func;
Does that look more readable to you? Or maybe like that?
// Careful! Wrong!
int ()(int, int) *func;
This syntax is not very clear either and it doesn't mimic any other existing C syntax. If you work a lot with function pointers, pass them around and store them in variables, you should declare an own type for your function pointer:
#include <stdio.h>
int sum ( int a, int b ) {
return (a + b);
}
typedef int (* MathFuncType)(int, int);
MathFuncType getSumFunc ( ) {
return ∑
}
int main(void) {
MathFuncType func = getSumFunc();
printf("%d\n", func(3, 8));
return 0;
}
http://rextester.com/GEKR20461

Related

C pass pointer as argument in function [duplicate]

This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed 6 years ago.
I came across the following code:
int H3I_hook(int (*progress_fn)(int*), int *id)
{
...
}
I don't understand the purpose of (int*) at the end of the first argument?
Demystifying:
int (*progress_fn)(int*)
it can be interpreted like below:
int (*progress_fn)(int*)
^ ^ ^
| | |___________ pointer to integer as argument
| |
| pointer to any function that has V and takes ^
|
|__________________________return type an integer
int (*progress_fn)(int*) is function pointer decleration, and (int *) is the list of parameters the function accepts.
So, this:
int (*progress_fn)(int*)
is a pointer to a function that will return an int and will receive one parameter, of type int*.
So you have to understand that progess_fn is the actual parameter. All its relevant components define how the function's prototype is actually.
For more, read How do function pointers in C work?
Given this declarartion:
int progress_callback(int* a);
// ^ this is the (int*) you asked about
You can call H3I_hook like this:
int id = something;
int x = H3I_hook(progress_callback, &id);

Is passing variables as arguments & getting desired return value essentially same as passing pointers?

I tried two approaches for passing values to functions, and both seem to have same effect.
1) Passing pointers
int foo(int *bar){
*bar = doSomething();
}
int main(void){
int foobar = 0;
foo(&foobar);
}
2) Passing variables
int foo(int bar){
//do stuff
return bar;
}
int main(void){
int foobar = 0;
foobar = foo(foobar);
}
So does it mean that using appropriate return i can simulate the same effect as when I use pointers as arguments?Are they basically same and it's just a matter of choice and style/syntax?
I hear pointers complicate code and so as a general rule of thumb one should avoid pointers.
Half of C is pointer, you haven't got what C is until you master the pointer concept.
It's not always possible to use just return value. In fact, many APIs uses return value only as success/error indicator code, while the real return value is put in the pointer parameter. For instance, a networking library might have the following usage:
if (AcceptClient(&ClientInfo) == SUCCESS) { ... }
Pointer parameter also serves for multiple return value:
if (GetConfigString(&StrData,&StrLen) == OK) { ... }
One cannot really avoid pointers when programming in C. However, in languages with pointer abstraction support, that is where pointer to many different objects is managed and the complication is hidden from programmers, it's indeed better to use the abstraction rather than the plain pointer as it reduces a lot of problems that might occur when dealing with pointers. For instance, in Object Pascal you have dynamic arrays, ansistrings, widestrings, etc. All of them are pointer abstraction. One does not need to handle the storage (de)allocation, access of elements, do range checking, etc. everything is handled by the code injected by the compiler. Thus, even when an error happens (e.g. accessing element outside of valid indexes), the error is easily tracable.
In this particular example both has the same effect: they both update the value of foobar, but the way in which they are updated are completely different.
In the case 1 you pass the address of foobar inside main to the function foo. This address of foobar gets stored into the bar argument variable in the function foo, and bar points to foobar. Because now you have the address of foobar and the object's lifetime has not finished, you can access the storage of foobar directly , and modify it.
+--------+
| 55 | +------call foo(&foobar)-----+
+--------+ | |
int | foobar | | V
+--------+ | +--points to--------+--------+
| 0x1234 |-----+ | | 0x1234 |
+--------+<---------+ +--------+
bar ( int * | bar | )
+--------+
| 0xabcd |
+--------+
At this moment bar holds the address of foobar
*bar = whatever will assign whatever to the address
which is held by bar, and thus changing the value
of foobar in main
In case 2, thing is different. You pass the value of foobar to foo which is held up in the variable bar. In foo you do not have direct access to the object foobar. You can do whatever you want with the value inside foo, it won't affect the foobar. When you return some value, foobar = foo(foobar); statement assigns the returned value into foobar this is when foobar gets updated.
+--------+
| 55 |-------------call foo(foobar)-----+
+--------+ |
int | foobar |<-+ V
+--------+ | +--------+
| 0x1234 | | | 55 |
+--------+ | +--------+
| bar ( int * | bar | )
| +--------+
foobar = foo(foobar); | 0xabcd |
| +--------+
| {
| //change bar
|
+-------------- return bar;
}
Here bar does not point to anything, it just has
copy of the value of foobar. Whatever is returned
by foo will be assigned in foobar in main
A point to note is that, when you pass the address, actually a value is copied to the bar, which is later interpreted as an address. I suggest to read more about pointers, it's a powerful tool.
They may seem the same but there's not!!Even though both use pass-by-value to pass arguments,how they are used is very much different.When you pass pointers as arguments to a function,whatever manipulations you carry out by dereferencing those pointers in that function body are reflected in the original values of the variables that these pointers point to,even though these passed pointers may be copies of the "original" pointers declared in main().You see, more than one pointers can point to a variable and hence the variables' values can be changed by dereferencing any of these pointers.
But while you pass variables as arguments,instead of pointers, all manipulations on the value of those variables are not reflected in the values of the "original" variables.Those changes are confined to those copies that are passed as parameters.
In your example,had you wished to assign the value of return of foo() or that of doSomething() to a variable other than bar and intended not to alter bar's value,then only passing variables as argument is desirable,not pointers.
Here is some simple code that illustrates it:
//Passing variables as arguments
#include<stdio.h>
int foo(int bar){
bar=303;
}
int main(void)
{
int foobar = 0;
printf("The value of foobar before function call is %d\n",foobar);
foo(foobar);
printf("TThe value of foobar after function call is %d",foobar);
}
Output : The value of foobar before function call is 0
`The value of foobar after function call is 303`
//Passing pointers to variables as arguments
#include<stdio.h>
int doSomething();
int foo(int *bar){
*bar = doSomething();
}
int main(void){
int foobar = 0;
printf("The value of foobar before function call is %d\n",foobar);
foo(&foobar);
printf("TThe value of foobar after function call is %d",foobar);
}
int doSomething()
{
return 303;
}
Output : The value of foobar before function call is 0
`The value of foobar after function call is 0`
And at last,about pointers making code complicated,well,pointers are one of the most elegant features of C and are a very useful and indispensable tool once you know how to use them well.
Its a little more than "matter of style" discussion here. Code is written so the machine works, but 99.9% of "real-world" code is written for humans to understand.
And humans understand words, sentences, idioms etc.
One of the common idioms in C is:
"If a function must change/alter the contents of an object(variables, structures variables, union variables etc) then pass the handle to the object by value."
Which means, you must pass-the-object-by-reference to the function. This is where your approach#1 works well, and seasoned programmers know what you are trying to do with it.
On the other hand another idiom says:
"If the function behaves like a purely mathematical function, where f(x) is always equal to y, then pass the object itself by value, and use the return value"(not sure if I framed it well)
Which means, for every x, if the value of f(x) never changes, then use the approach#2.
This conveys the other programmers exactly what you are trying to do. I hope this explanation helps.
Regardless, both approaches do the same work, and outputs are the same.
Yes, either style works. There are pros and cons to each.
The return style can take constant arguments.
int foo(int bar); foo(42); // works
void foo(int *bar); foo(42); // nope
void foo(int *bar); foo(&42); // still nope
The pass-by-address style (also known as "out-parameters") relieves string functions (for example) of memory management, and lets them return an error code.
int strcpy(char *src, char *dst) { /* nice simple while loop */ }
char *strcpy(char *src) { /* welcome to malloc hell */ }
Also, pass-by-address can save stack space and copying overhead when working with structs.
struct quux { /* lots and lots of stuff */ };
struct quux foo(int bar) { ...; return s; /* have to fit a struct quux on stack */ }
int foo(int bar, struct quux *result) { /* write stuff into *result */; }
In general, it is preferred to return where at all possible, and only use out-parameters where necessary.
ya both are same. you could use anything. But, your first code must be
int foo(int *bar){
*bar = doSomething();
}
int main(void){
int foobar = 0;
foo(&foobar);
}
Because bar is of pointer type and it needs an address of the variable as argument.
Hence foobar will be a variable and &foobar will be pointer.
Generally, these things will be called as call by value, call by address.
Refer wiki for call by value, and call by address.
//Call by Address
void SwapIntAddr(int* ptmp1, int* ptmp2)
{
int ptmp;
ptmp = *ptmp1;
*ptmp1 = *ptmp2;
*ptmp2 = ptmp;
}
//Call by Value
void SwapIntVal(int tmp1, int tmp2)
{
int tmp;
tmp = tmp1;
tmp1 = tmp2;
tmp2 = tmp;
}
int main(){
int a = 3, b= 5;
SwapIntVal(a,b); // This will have no effect
printf("%d %d\n",a,b);
SwapIntAddr(&a,&b); // This will have effect
printf("%d %d\n",a,b);
}
Refer my answer here for more detailed example.

How do I declare a function to be used as a function pointer in c?

I am confused with function pointer declaration.
I have an api abc() which takes an argument as so:
void abc(void (*my_func)(void *p), int, int)
If I want to pass my function as an argument to that api, I am declaring it in my .h file:
void (*xyz)(void *p)
and defining as:
void *(xyz)(void *p){
statements;
}
but this throws an error. Please correct me.
you just need to declare it:
void xyz(void *p);
with the implementation the same way.
When you pass it into your api, the type system figures out it out automatically:
abc(xyz,someint,anotherint);
The (*xyz) means that it is a function pointer.
Function pointers are best handled with typedefs. So it is guaranteed that there is nothing wrong.
I would do the following:
// define a type for the function (not its pointers, as you can often read)
typedef void my_func_t(void *p);
void abc(my_func_t*, int, int);
// declaration in order to be type-safe - impossible if only the pointer would be typedef'd
my_func_t my_func_impl;
// definition:
void my_func_impl(void *p)
{
do_something_with(p);
}
and then you can call your abc() with abc(my_func_impl, 47, 11). You can put a & before my_func_impl there in order to point out that it is the function address you wish to obtain, but it is optional.
An alternative would be to write
typedef void (*my_func_p)(void *p);
and use my_func_p instead of my_func_t *, but this has the disadvantage that you cannot write my_func_t my_func_impl;.
Why would you want to do that?
Well, if, by any coincidence or accident, the function definition or the typedef is changed, they won't match any longer, but the collision is not declared as error, but only as warning (Mismatch pointer). OTOH, my_func_t my_func_impl; serves as a kind of prototype, which causes a function header mismatch, which is an error.
Simply declare and define your function as you would any other:
void xyz(void *p);
void xyz(void *p){
// ...
}
and pass a pointer to the API:
abc(xyz, 42, 7);
Function names are automatically interpreted as function pointers where appropriate. You can also explicitly take the address of the function, if brevity isn't your thing:
abc(&xyz, 42, 7);
If I understood correctly, you want xyz to be the function that is passed to abc, right?
As the argument my_func indicates, you have a pointer to a function that takes void * as argument and returns void
type (*func_pointer)(type, type, type, .......)
^ ^ ^ ^ ^ ^
| | | | | |
| | | argument types
| | pointer name
| This is a function pointer
return type
Therefore, you need to declare xyz as:
void xyz(void *p);
And the same in implementation:
void xyz(void *p){
statements;
}
What you are doing wrong is that, the line you wrote in the .h file defines a function pointer, named xyz. The function pointer has no value, because you never wrote xyz = some_function;
What you have written in the source file is a function, also with name xyz that takes a void * as input and returns a void *, instead of void which was your intention.
Maybe this helps you get less confused:
When you write int *x;, x is a pointer to int. Then you can have int y; that doesn't have an extra * and write x = &y;.
It's the same with functions. If you have void (*funcptr)(void *p);, then all you need is a function that says void some_func(void *p){} (again without the extra *) and write funcptr = some_func;. You don't need the & since function names are in fact pointer to the function. You could put it to be more explicit though.
The first argument of 'abc' is the pointer of function returning 'void' and having 'void *' as an argument...
So your code should look like:
void
myFunc (void *)
{
// ... my statements
}
...
abc (myFunc, 10, 20);
This works
void abc(void* (*my_func)(void*), int a, int b) {
my_func(0);
}
void *(xyz)(void *p) {}
int main() {
abc(xyz, 0, 0);
return 0;
}
When you write void (*my_func)(void *p) it means pointer to function, that returns void
And void (*my_func)(void *p) it means pointer to function, that returns pointer

Function declaration

int func(void) [5];
Why is above line not valid in c ? As anyone knows, function can be used as variable. But, I don't understand why compiler gives error .
Why I used that line is because I have tried to create 5 function-variable. To do so, I wrote like that, shown above.
Because it doesn't meet the C language valid syntax?
May be you should specify what are you trying to do with that sentence in order to get the answer you might be looking for.
This is not legal C syntax, period.
It is invalid in C++ too because functions cannot be put in arrays (you are trying to declare an array of five functions). However, the following works both in C and C++:
int (*func[5])(); // C++ version
int (*func[5])(void); // C version
and declares an array of five function pointers.
If you instead want a function which returns an array, in C you do
int *func(void);
and in C++ you do
int* func();
or
int (&func())[5];
which returns a reference to an array of five integers.
From the C standard (n1256):
6.7.5.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Functions cannot return array types or other function types. Functions can return pointers to those types, though:
int (*func(void))[5];
The syntax is a little weird looking, but it breaks down as follows:
func -- func
func(void) -- is a function taking no parameters
*func(void) -- returning a pointer
(*func(void))[5] -- to a 5-element array
int (*func(void))[5] -- of int
This isn't as useful as it looks: if you try to return a pointer to a local array, such as
int (*func(void))[5]
{
int arr[5] = {0,1,2,3,4};
return &arr;
}
the array no longer exists when the function returns; the pointer value you get back won't point to anything meaningful anymore.
If you're trying to create an array of functions, you have a similar problem; you cannot have an array of function types (6.7.5.2, paragraph 1, which includes the sentence "The element type shall not be an incomplete or function type"), although you can have an array of pointers to functions:
int (*func[5])(void);
This breaks down as
func -- func
func[5] -- is a 5-element array
*func[5] -- of pointers
(*func[5])(void) -- to functions taking no parameters
int (*func[5])(void) -- and returning int
Example:
int f0(void) { return 0; }
int f1(void) { return 1; }
int f2(void) { return 2; }
int f3(void) { return 3; }
int f4(void) { return 4; }
int main(void)
{
int (*func[5])(void) = {f0, f1, f2, f3, f4};
int i;
for (i = 0; i < 5; i++)
printf("f%d = %d\n", i, (*func[i])()); // or just func[i]()
return 0;
}
It is trying to declare a function that returns an array. This is not allowed - and it's nothing to do with syntax, it's a semantic rule, as demonstrated by the following (which has exactly the same problem, but is obviously syntactically fine):
typedef int FiveInts[5];
FiveInts func(void);
This is part of the "arrays are special" type rules in C. Function return values are not lvalues, and the only context in which a non-lvalue array could be used is as the subject of the sizeof operator. This makes functions returning array types completely useless.
try :
int *func(void);

Understanding functions and pointers in C

This is a very simple question but what does the following function prototype mean?
int square( int y, size_t* x )
what dose the size_t* mean? I know size_t is a data type (int >=0). But how do I read the * attached to it? Is it a pointer to the memory location for x? In general I'm having trouble with this stuff, and if anybody could provide a handy reference, I'd appreciate it.
Thanks everybody. I understand what a pointer is, but I guess I have a hard hard time understanding the relationship between pointers and functions. When I see a function prototype defined as int sq(int x, int y), then it is perfectly clear to me what is going on. However, when I see something like int sq( int x, int* y), then I cannot--for the life of me--understand what the second parameter really means. On some level I understand it means "passing a pointer" but I don't understand things well enough to manipulate it on my own.
How about a tutorial on understanding pointers?
In this case however, the pointer is probably used to modify/return the value. In C, there are two basic mechanisms in which a function can return a value (please forgive the dumb example):
It can return the value directly:
float square_root( float x )
{
if ( x >= 0 )
return sqrt( x );
return 0;
}
Or it can return by a pointer:
int square_root( float x, float* result )
{
if ( x >= 0 )
{
*result = sqrt( result );
return 1;
}
return 0;
}
The first one is called:
float a = square_root( 12.0 );
... while the latter:
float b;
square_root( 12.00, &b );
Note that the latter example will also allow you to check whether the value returned was real -- this mechanism is widely used in C libraries, where the return value of a function usually denotes success (or the lack of it) while the values themselves are returned via parameters.
Hence with the latter you could write:
float sqresult;
if ( !square_root( myvar, &sqresult ) )
{
// signal error
}
else
{
// value is good, continue using sqresult!
}
*x means that x is a pointer to a memory location of type size_t.
You can set the location with x = &y;
or set the value were x points to with: *x = 0;
If you need further information take a look at: Pointers
The prototype means that the function takes one integer arg and one arg which is a pointer to a size_t type. size_t is a type defined in a header file, usually to be an unsigned int, but the reason for not just using "unsigned int* x" is to give compiler writers flexibility to use something else.
A pointer is a value that holds a memory address. If I write
int x = 42;
then the compiler will allocate 4 bytes in memory and remember the location any time I use x. If I want to pass that location explicitly, I can create a pointer and assign to it the address of x:
int* ptr = &x;
Now I can pass around ptr to functions that expect a int* for an argument, and I can use ptr by dereferencing:
cout << *ptr + 1;
will print out 43.
There are a number of reasons you might want to use pointers instead of values. 1) you avoid copy-constructing structs and classes when you pass to a function 2) you can have more than one handle to a variable 3) it is the only way to manipulate variables on the heap 4) you can use them to pass results out of a function by writing to the location pointed to by an arg
Pointer Basics
Pointers And Memory
In response to your last comment, I'll try and explain.
You know that variables hold a value, and the type of the variable tells you what kind of values it can hold. So an int type variable can hold an integer number that falls within a certain range. If I declare a function like:
int sq(int x);
...then that means that the sq function needs you to supply a value which is an integer number, and it will return a value that is also an integer number.
If a variable is declared with a pointer type, it means that the value of that variable itself is "the location of another variable". So an int * type variable can hold as its value, "the location of another variable, and that other variable has int type". Then we can extend that to functions:
int sqp(int * x);
That means that the sqp function needs to you to supply a value which is itself the location of an int type variable. That means I could call it like so:
int p;
int q;
p = sqp(&q);
(&q just means "give me the location of q, not its value"). Within sqp, I could use that pointer like this:
int sqp(int * x)
{
*x = 10;
return 20;
}
(*x means "act on the variable at the location given by x, not x itself").
size_t *x means you are passing a pointer to a size_t 'instance'.
There are a couple of reasons you want to pass a pointer.
So that the function can modify the caller's variable. C uses pass-by-value so that modifying a parameter inside a function does not modify the original variable.
For performance reasons. If a parameter is a structure, pass-by-value means you have to copy the struct. If the struct is big enough this could cause a performance hit.
There's a further interpretation given this is a parameter to a function.
When you use pointers (something*) in a function's argument and you pass a variable you are not passing a value, you are passing a reference (a "pointer") to a value. Any changes made to the variable inside the function are done to the variable to which it refers, i.e. the variable outside the function.
You still have to pass the correct type - there are two ways to do this; either use a pointer in the calling routine or use the & (addressof) operator.
I've just written this quickly to demonstrate:
#include <stdio.h>
void add(int one, int* two)
{
*two += one;
}
int main()
{
int x = 5;
int y = 7;
add(x,&y);
printf("%d %d\n", x, y);
return 0;
}
This is how things like scanf work.
int square( int y, size_t* x );
This declares a function that takes two arguments - an integer, and a pointer to unsigned (probably large) integer, and returns an integer.
size_t is unsigned integer type (usually a typedef) returned by sizeof() operator.
* (star) signals pointer type (e.g. int* ptr; makes ptr to be pointer to integer) when used in declarations (and casts), or dereference of a pointer when used at lvalue or rvalue (*ptr = 10; assigns ten to memory pointed to by ptr). It's just our luck that the same symbol is used for multiplication (Pascal, for example, uses ^ for pointers).
At the point of function declaration the names of the parameters (x and y here) don't really matter. You can define your function with different parameter names in the .c file. The caller of the function is only interested in the types and number of function parameters, and the return type.
When you define the function, the parameters now name local variables, whose values are assigned by the caller.
Pointer function parameters are used when passing objects by reference or as output parameters where you pass in a pointer to location where the function stores output value.
C is beautiful and simple language :)
U said that u know what int sq(int x, int y) is.It means we are passing two variables x,y as aguements to the function sq.Say sq function is called from main() function as in
main()
{
/*some code*/
x=sr(a,b);
/*some other code*/
}
int sq(int x,int y)
{
/*code*/
}
any operations done on x,y in sq function does not effect the values a,b
while in
main()
{
/*some code*/
x=sq(a,&b);
/*some other code*/
}
int sq(int x,int* y)
{
/*code*/
}
the operations done on y will modify the value of b,because we are referring to b
so, if you want to modify original values, use pointers.
If you want to use those values, then no need of using pointers.
most of the explanation above is quite well explained. I would like to add the application point of view of this kind of argument passing.
1) when a function has to return more than one value it cannot be done by using more than one return type(trivial, and we all know that).In order to achieve that passing pointers to the function as arguments will provide a way to reflect the changes made inside the function being called(eg:sqrt) in the calling function(eg:main)
Eg: silly but gives you a scenario
//a function is used to get two random numbers into x,y in the main function
int main()
{
int x,y;
generate_rand(&x,&y);
//now x,y contain random values generated by the function
}
void generate_rand(int *x,int *y)
{
*x=rand()%100;
*y=rand()%100;
}
2)when passing an object(a class' object or a structure etc) is a costly process (i.e if the size is too huge then memory n other constraints etc)
eg: instead of passing a structure to a function as an argument, the pointer could be handy as the pointer can be used to access the structure but also saves memory as you are not storing the structure in the temporary location(or stack)
just a couple of examples.. hope it helps..
2 years on and still no answer accepted? Alright, I'll try and explain it...
Let's take the two functions you've mentioned in your question:
int sq_A(int x, int y)
You know this - it's a function called sq_A which takes two int parameters. Easy.
int sq_B(int x, int* y)
This is a function called sq_B which takes two parameters:
Parameter 1 is an int
Parameter 2 is a pointer. This is a pointer that points to an int
So, when we call sq_B(), we need to pass a pointer as the second
parameter. We can't just pass any pointer though - it must be a pointer to an int type.
For example:
int sq_B(int x, int* y) {
/* do something with x and y and return a value */
}
int main() {
int t = 6;
int u = 24;
int result;
result = sq_B(t, &u);
return 0;
}
In main(), variable u is an int. To obtain a pointer to u, we
use the & operator - &u. This means "address of u", and is a
pointer.
Because u is an int, &u is a pointer to an int (or int *), which is the type specified by parameter 2 of sq_B().
Any questions?

Resources