i want to ask a question about pointer:
void fun(const char** a) {...}
1.
const char* b = nullptr;
fun(&b);
2.
const char** b = nullptr;
fun(b);
why use 1 but not 2?
1 is good, 2 donnot work
C uses pass by value for function call arguments. That means a function receives a copy of the passed value, and there's no way for the function to directly change a variable in the caller.
For example, if you write
void set_to_5(int x)
{
x = 5;
}
and then write
int i = 3;
set_to_5(i);
printf("%d\n", i);
it prints 3
, not 5
. Or, if you write
void set_string(char *str)
{
str = "world";
}
and then write
char *p = "hello";
set_string(p);
printf("%s\n", p);
it prints hello
, not world
.
In both cases, the function successfully changes its copy of the passed value — x
or str
— but that doesn't have any effect on the variable in the caller (i
or p
).
When you want to have a function that does change a variable in its caller, one way to do that is to have the function accept a pointer. That looks like this:
void set_to_5_via_pointer(int *x)
{
*x = 5;
}
void set_string_via_pointer(char **str)
{
*str = "world";
}
Then you can write:
int i = 3;
set_to_5_via_pointer(&i);
printf("%d\n", i);
char *p = "hello";
set_string_via_pointer(&p);
printf("%s\n", p);
Now it does print 5
and world
, as desired.
Notice that in each case I made three changes:
*
to the parameter type expected by the function (int x
to int *x
, char *str
to char **str
)*
before each use of the parameter in the function, that is, where I actually set the new value (5
and "world"
)&
before the variables where I passed them to the function (set_to_5_via_pointer(&i)
and set_string_via_pointer(&p)
).One more thing. When you see a function declaration like
void set_string_via_pointer(char **str);
this does not necessarily mean that the right way to call the function is
char **x;
set_string_via_pointer(x);
Yes, here x
is of type char **
, and function set_string_via_pointer
expects an argument of type char **
, so it's a match. But if you declare and call
char *y;
set_string_via_pointer(&y);
that's also a perfectly good way to pass an argument of type char **
, and in this case, it's certainly they way that was expected.