Reputation: 178
void func(char *ptr) //Passed by reference
{
*ptr = 'B';
}
int main()
{
char *ptr;
ptr = (char *) malloc(sizeof(char) * 1);
*ptr = 'A';
printf("%c\n", *ptr);
func(ptr);
printf("%c\n", *ptr);
}
I was confuse I know that ptr=(char*)malloc (sizeof(char*1)
here means allocate 1 byte and return a pointer to the allocation then assign to ptr
, so ptr
is a pointer.
But when it calls func(ptr)
why it not use &
? Although what I want is to change the character inside ptr
points to? Why not using void func(char** ptr)
and send func(&ptr)
here? Is it possible?
I mean what made this pass by reference?
second code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *c=NULL;
test(c);
printf("after test string is %s\n",c);
return 0;
}
void test (char *a)
{
a=(char*)malloc(sizeof(char)*6);
a="test";
printf("inside test string is %s\n",a);
}
Upvotes: 0
Views: 1960
Reputation: 133879
In C there is really no such thing as "pass by reference". All arguments are passed by value - assigned as copies into the local variables - the parameters. Given a function like
void func(char *ptr);
the value passed in is a char *
- a pointer to char
, and within the function, the value stored in ptr
is a copy of the original value in the calling function, so that no changes in the value of ptr
itself within the callee would be seen outside in the caller.
But the value of that pointer - if it is valid - is also a reference to an object of type char
- or to an element of an array of type char[]
. In your case, it is the pointer to the first element of dynamically allocated array of 1 characters. Thus you indeed passed in - by value - a reference to an object of type char
.
Had you used func(&ptr);
the function prototype would need to be
void func(char **ptr);
that is, the argument would have to be a pointer to a pointer to char
. If you dereference the value once, with *ptr
, you get an lvalue (locator value) of type char *
; you can modify this as if it was a a variable. Or, you can dereference that pointer value too - i.e. **ptr
to get an lvalue
of type char
.
However, in the case of your function, if you just want to modify the stored char
, the change wouldn't have helped a bit, but instead make your code more complicated to use, as you'd now need a valid object of type char *
, whose address would be passed into the function; with void func(char *ptr)
, you just need a valid object of type char
.
Upvotes: 1
Reputation: 61969
Of course it is possible to do void func( char** ptr )
and invoke it with func( &ptr )
, but then you would not (only) be passing the character by reference, you would be passing the pointer by reference. So, in order to change the character, you would need to do **ptr = 'B';
inside func()
.
But if all you want to do is change the character pointed by ptr, then the additional level of indirection does not buy you anything.
You would use void func( char** ptr )
if you were planning to change the address that the pointer points to. That would look like this:
char b;
void func( char** ptr )
{
*ptr = &b;
}
Upvotes: 0
Reputation: 4991
When you call func
using ptr
as its parameter you are actually passing a char*
(since ptr
is a char*
).
If you were to use func(&ptr)
you'd pass a pointer to a pointer (here a char**
) but func requires a pointer to a char (char*
).
You can use void func(char**)
and func(&ptr)
but that would just add a "layer of pointer" for seemingly no reason (since in func you want to access the content you'd have to do **ptr
).
The call is pass-by-reference because you pass in a pointer (variable that holds the address in memory of another variable) not a value (variable itself).
Upvotes: 1