[英]C passing pointer to a function confusion
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.这来自一本很棒的 C 书,也许我质疑它太多,但不知何故它没有意义。 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;假设下面&a
指向 memory 地址 87, &b
指向 memory 地址 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?好的,问题来了:当我们调用 function 交换并将参数传递给 function时,我们实际上是将“px”设置为 87 还是将“*px”设置为 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.因为如果我们将 *px 设置为 87,那么根据*
符号的定义,我们设置的是指针所指的值,而不是 memory 地址 p 持有的值,这在本例中是错误的。 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.另一方面,如果我们实际上将“p”设置为 87,那么 swap 中的代码是有意义的,因为当我们在 function 中使用 * 符号时,我们将引用该地址中的值“3”这里。 But then why is the syntax confusing and looks like as if we are setting但是为什么语法令人困惑,看起来好像我们正在设置
*px = 87
? ?
If a
is at address 88 (needs to be aligned correctly) and b
is at address 120, then:如果a
在地址 88(需要正确对齐)并且b
在地址 120,则:
// 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
是&a
,它是88
,永远不会改变。 *px
refers to (aliases) a
. *px
指(别名) 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*
.参数是px
并且类型为int*
。 The parameter is not *px
.该参数不是*px
。 For this reason, many programmers write it as int* px
instead of int *px
.出于这个原因,许多程序员将其写为int* px
而不是int *px
。 The effect of calling swap(&a, &b)
is that px = &a
and not *px = &a
.调用swap(&a, &b)
的效果是px = &a
而不是*px = &a
。
But please note, C doesn't have "methods", only "functions".但请注意,C 没有“方法”,只有“功能”。
Consider your signature of swap
:考虑您的swap
签名:
void swap(int *px, int *py);
This means that swap takes two pointers to int
.这意味着 swap 需要两个指向int
的指针。 Another way to put it: it takes two addresses of int
values in memory.换一种说法:它取memory中的两个int
值地址。
Now, when calling your swap
function like现在,当调用你的swap
function 时
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).第一个参数将是a
的地址(它是一个int
),第二个参数将是b
的地址(它也是一个int
)。
Inside swap
, px
will be the address of a
and py
will be the address of b
.在swap
中, px
将是a
的地址, py
将是b
的地址。 Consequently, dereferencing px
and py
will yield the values at the addresses of a
and b
- which would be 3 and 4.因此,取消引用px
和py
将在a
和b
的地址处产生值 - 这将是 3 和 4。
*
may mean three different things, depending on the context: *
可能意味着三种不同的东西,具体取决于上下文:
a * b
, it means multiplication.在a * b
中,它表示乘法。int *a
, it means "we are now declaring a variable or parameter a
, whose type is int *
(pointer to int
).在int *a
中,它的意思是“我们现在声明一个变量或参数a
,其类型为int *
(指向int
的指针)。*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".在*a
中(假设*
左边没有数据类型,所以这是一个表达式而不是声明),它的意思是“ a
是一个指针,我们要查看它指向的值(也称为取消引用指针”。 So the parameter to your method is a
, not *a
;所以你的方法的参数是a
,而不是*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.星号是参数类型的一部分, a
是您设置为 87 的值。将指针声明编写为int * a
或int* a
而不是int *a
可能有助于更清楚地区分声明和取消引用。
void swap(int *px, int *py)
You read this that px
and py
point to int
.你读到这个px
和py
指向int
。 Parameters in C are passed by value. C中的参数是按值传递的。 So when you pass two memory addresses (ie pointers) to swap
you are assigning those addresses to px
and py
.因此,当您传递两个 memory 地址(即指针)进行swap
时,您将这些地址分配给px
和py
。
Perhaps the confusion is due to the heavy overloading of *
in C.也许混淆是由于 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.在 function 的实现中, *
用于取消引用指针。
You aren't setting any pointers, you always only set the value of the pointee .您没有设置任何指针,您始终只设置pointee的值。 *px = *py
will set a
to the value of b
. *px = *py
将a
设置为b
的值。
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
).变量a
指向 memory 地址 87。 &a
是87。然后我们将px
设置为 87。当然,这些是地址而不是整数,但这与 CPU 上发生的情况非常接近(当然在 CPU 上没有'不是任何a
, &a
或px
)。
Are we actually setting " px " to 87 or are we setting " *px " to 87?我们实际上是将“px”设置为 87 还是将“*px”设置为 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.是的,您将px设置为 87。您正在使指针指向相同的位置,同时更改它们指向的值。
"Because if we are setting *px to 87"... “因为如果我们将 *px 设置为 87”...
No, your assumption is wrong.不,你的假设是错误的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.