问题
I am a bit confused here. This is from a great C book, and maybe I question it too much, but somehow it didn't make sense. I hope I can tell my confusion.
Let's say below &a
points to the memory address 87 and &b
points to the memory address 120;
int a = 3;
int b = 4;
swap(&a, &b);
void swap(int *px, int *py) {
int temp;
temp = *px;
*px = *py;
*py = temp;
}
OK, here is the question: When we call function swap and pass the parameters to the function are we actually setting "px" to 87 or are we setting "*px" to 87?
Because if we are setting *px to 87 then by definition of the *
sign, we are setting the value where the pointer refers to, but not the memory address p holds, which is wrong in this example. On the other hand, if there we are actually setting "p" to 87 then the code in swap makes sense, because then when we use the * sign in the function we will be referring to the value in that address which is "3" here. But then why is the syntax confusing and looks like as if we are setting
*px = 87
?
回答1:
*
may mean three different things, depending on the context:
- In
a * b
, it means multiplication. - In
int *a
, it means "we are now declaring a variable or parametera
, whose type isint *
(pointer toint
). - In
*a
(assuming that there is no data type to the left of*
, so that this is an expression and not a declaration), it means "a
is a pointer, and we want to look at the value it points to (also known as dereferencing the pointer".
So the parameter to your method is a
, not *a
; the asterisk is part of the parameter's type, and a
is what you are setting to 87. Writing pointer declarations as int * a
or int* a
instead of int *a
may help making the distinction between declaration and dereferencing clearer.
回答2:
If a
is at address 88 (needs to be aligned correctly) and b
is at address 120, then:
// a | b | px | py | temp
int a=3; // 3 -- -- -- --
int b=4; // 3 4 -- -- --
swap(&a, &b); // 4 3 -- -- --
void swap(int *px, int *py)
{ // 3 4 88 120 --
int temp;
temp = *px; // 3 4 88 120 3
*px = *py; // 4 4 88 120 3
*py = temp; // 4 3 88 120 3
}
px
is &a
which is 88
, never changes.
*px
refers to (aliases) a
. It could be rebound to alias a different variable, but this code doesn't do that.
The parameter is px
and has type int*
. The parameter is not *px
. For this reason, many programmers write it as int* px
instead of int *px
. The effect of calling swap(&a, &b)
is that px = &a
and not *px = &a
.
But please note, C doesn't have "methods", only "functions".
回答3:
Consider your signature of swap
:
void swap(int *px, int *py);
This means that swap takes two pointers to int
. Another way to put it: it takes two addresses of int
values in memory.
Now, when calling your swap
function like
swap(&a, &b);
the first argument will be the address of a
(which is an int
), and the second argument will be the address of b
(which is an int
as well).
Inside swap
, px
will be the address of a
and py
will be the address of b
. Consequently, dereferencing px
and py
will yield the values at the addresses of a
and b
- which would be 3 and 4.
回答4:
void swap(int *px, int *py)
You read this that px
and py
point to int
. Parameters in C are passed by value. So when you pass two memory addresses (i.e. pointers) to swap
you are assigning those addresses to px
and py
.
Perhaps the confusion is due to the heavy overloading of *
in C. In a parameter list *
means that the parameter is a pointer to the type to the left. In the implementation of a function, *
is used to dereference a pointer.
回答5:
You aren't setting any pointers, you always only set the value of the pointee. *px = *py
will set a
to the value of b
.
回答6:
Variable a
points to memory address 87. &a
is 87. And then we are setting px
to 87. Of course, these are addresses and not integers, but that's very close to what is happening on the CPU (of course on the CPU there isn't any a
, &a
or px
).
回答7:
Are we actually setting " px " to 87 or are we setting " *px " to 87?
Yes, you are setting px to 87. You are making the pointers point to the same location while changing the values they are pointing at.
"Because if we are setting *px to 87" ...
No, your assumption is wrong.
来源:https://stackoverflow.com/questions/6574500/c-passing-pointer-to-a-function-confusion