简体   繁体   English

C 将指针传递给 function 混淆

[英]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.因此,取消引用pxpy将在ab的地址处产生值 - 这将是 3 和 4。

* may mean three different things, depending on the context: *可能意味着三种不同的东西,具体取决于上下文:

  • In a * b , it means multiplication.a * b中,它表示乘法。
  • In 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的指针)。
  • 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".*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 * aint* a而不是int *a可能有助于更清楚地区分声明和取消引用。

void swap(int *px, int *py) 

You read this that px and py point to int .你读到这个pxpy指向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时,您将这些地址分配给pxpy

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 = *pya设置为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。 &a87。然后我们将px设置为 87。当然,这些是地址而不是整数,但这与 CPU 上发生的情况非常接近(当然在 CPU 上没有'不是任何a&apx )。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM