[英]C passing pointer to a function confusion
我在这里有点困惑。 这来自一本很棒的 C 书,也许我质疑它太多,但不知何故它没有意义。 我希望我能说出我的困惑。
假设下面&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;
}
好的,问题来了:当我们调用 function 交换并将参数传递给 function时,我们实际上是将“px”设置为 87 还是将“*px”设置为 87?
因为如果我们将 *px 设置为 87,那么根据*
符号的定义,我们设置的是指针所指的值,而不是 memory 地址 p 持有的值,这在本例中是错误的。 另一方面,如果我们实际上将“p”设置为 87,那么 swap 中的代码是有意义的,因为当我们在 function 中使用 * 符号时,我们将引用该地址中的值“3”这里。 但是为什么语法令人困惑,看起来好像我们正在设置
*px = 87
?
如果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
是&a
,它是88
,永远不会改变。 *px
指(别名) a
。 它可能会被重新绑定到别名不同的变量,但这段代码并没有这样做。
参数是px
并且类型为int*
。 该参数不是*px
。 出于这个原因,许多程序员将其写为int* px
而不是int *px
。 调用swap(&a, &b)
的效果是px = &a
而不是*px = &a
。
但请注意,C 没有“方法”,只有“功能”。
考虑您的swap
签名:
void swap(int *px, int *py);
这意味着 swap 需要两个指向int
的指针。 换一种说法:它取memory中的两个int
值地址。
现在,当调用你的swap
function 时
swap(&a, &b);
第一个参数将是a
的地址(它是一个int
),第二个参数将是b
的地址(它也是一个int
)。
在swap
中, px
将是a
的地址, py
将是b
的地址。 因此,取消引用px
和py
将在a
和b
的地址处产生值 - 这将是 3 和 4。
*
可能意味着三种不同的东西,具体取决于上下文:
a * b
中,它表示乘法。int *a
中,它的意思是“我们现在声明一个变量或参数a
,其类型为int *
(指向int
的指针)。*a
中(假设*
左边没有数据类型,所以这是一个表达式而不是声明),它的意思是“ a
是一个指针,我们要查看它指向的值(也称为取消引用指针”。 所以你的方法的参数是a
,而不是*a
; 星号是参数类型的一部分, a
是您设置为 87 的值。将指针声明编写为int * a
或int* a
而不是int *a
可能有助于更清楚地区分声明和取消引用。
void swap(int *px, int *py)
你读到这个px
和py
指向int
。 C中的参数是按值传递的。 因此,当您传递两个 memory 地址(即指针)进行swap
时,您将这些地址分配给px
和py
。
也许混淆是由于 C 中的*
重载所致。 在参数列表中*
表示参数是指向左侧类型的指针。 在 function 的实现中, *
用于取消引用指针。
您没有设置任何指针,您始终只设置pointee的值。 *px = *py
将a
设置为b
的值。
变量a
指向 memory 地址 87。 &a
是87。然后我们将px
设置为 87。当然,这些是地址而不是整数,但这与 CPU 上发生的情况非常接近(当然在 CPU 上没有'不是任何a
, &a
或px
)。
我们实际上是将“px”设置为 87 还是将“*px”设置为 87?
是的,您将px设置为 87。您正在使指针指向相同的位置,同时更改它们指向的值。
“因为如果我们将 *px 设置为 87”...
不,你的假设是错误的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.