繁体   English   中英

指向指针参数变量的指针以及它们如何工作? 例如function(int ** ptr)

[英]Pointer to pointer argument variable and how they work? e.g. function(int **ptr)

我正在编写代码,以了解将指针作为函数中的参数传递时会发生什么。

void ptrTest(int **arg_ptr); 

int main() {
    int some_var = 5;
    int *ptr1;
    ptr1 = &some_var;

    printf("Address of some_var: %u\n\n", &some_var);
    printf("Value stored in *ptr1 (references to some_var): %u\n", ptr1);
    printf("Address of *ptr1 variable: %u\n\n", &ptr1);
    ptrTest(ptr1);
}

void ptrTest(int **arg_ptr){
    printf("Value stored in **arg_ptr (references to some_var): %u\n",arg_ptr);    
}

结果如下:

Address of some_var: 3119323004

Value stored in *ptr1 (references to some_var): 3119323004
Address of *ptr1 variable: 3119322992

Value stored in **arg_ptr (references to some_var): 3119323004

令我惊讶的是arg_ptr引用了指向some_var地址的值。 我期望** arg_ptr指向* ptr并存储3119322992的值(引用* ptr的地址)。

当我测试指向函数外部的指针时,它的行为确实如此。 为什么指针作为参数的指针不同呢?

你能告诉我这里发生了什么吗?

首先是什么指针? C / C ++中的指针与其他类型如int,char等的变量一样。但是此变量的特殊之处在于,它与其他变量不同,它仅保存内存位置的地址。 同样,该内存位置也可能是指针变量或任何其他常规变量(int或char)。

现在什么是指针指针? 可以存储指针变量的地址的变量,并且该指针变量可能包含另一个变量的地址,例如:

 int i = 10; //`i` is assign with a value  10 and `i` has its own address which we can get by `&i`;

 int *ptr1 = &i;// now ptr1 is pointer to `i` means ptr1 is assign with the
 //address of `i` hence if we dereference the address of *ptr1 we will get the value stored at that memory location

现在你的情况

 void ptrTest(int **arg_ptr){
    printf("Address store in of **arg_ptr: %u\n",arg_ptr);    
}

所以在这里它会像下面一样工作

int **arg_ptr = ptr1;//Wrong, `ptr1` is assign to `arg_ptr`, which is wrong because `arg_ptr` is a pointer to pointer type

所以在这里您应该存储指针的地址,但是要存储变量int的地址,即i 因为i地址已在语句int * ptr1 =&i;中分配。 到ptr1。 正确的分配是

arg_ptr = &ptr1; //address of a pointer not address of a int variable.

现在首先取消引用:

  *arg_ptr; //value of a pointer ptr1 that means address of `i`

 *(*arg_ptr); or **arg_ptr;// we further dereferenced the address of ptr1 here, which is value 10

现在您应该像下面这样调用函数:

ptrTest(&ptr1);// address of a pointer.

ptrTest需要一个int **类型的参数,但是您正在传递int* 您的编译器应该抱怨。 您需要将ptr的地址传递给函数。

ptrTest(&ptr1);  

除此之外,您应该使用%p规范来打印地址。

printf("Address of some_var: %p\n\n", (void*)&some_var);

当我编译您的代码时,我会得到一长串错误:

"test.c", line 11: warning #2181-D: argument is incompatible with
          corresponding format string conversion
      printf("Address of some_var: %u\n\n", &some_var);
                                            ^

"test.c", line 12: warning #2181-D: argument is incompatible with
          corresponding format string conversion
      printf("Value stored in *ptr1 (references to some_var): %u\n", ptr1);
                                                                     ^

"test.c", line 13: warning #2181-D: argument is incompatible with
          corresponding format string conversion
      printf("Address of *ptr1 variable: %u\n\n", &ptr1);
                                                  ^

"test.c", line 14: warning #2167-D: argument of type "int *" is incompatible
          with parameter of type "int **"
      ptrTest(ptr1);
              ^

"test.c", line 18: warning #2181-D: argument is incompatible with
          corresponding format string conversion
      printf("Value stored in **arg_ptr (references to some_var): %u\n",arg_ptr);

让我们重写这段代码,使其编译时不会出错,并且可能会更清晰一些:

#include <stdio.h>

void ptrTest(int **arg_ptr)
  {
  printf("Value stored in arg_ptr (points to ptr1): %#p\n", arg_ptr);
  printf("Value pointed to by arg_ptr (i.e. *arg_ptr - should be same as ptr1): %#p\n", *arg_ptr);
  printf("Value pointed to by *arg_ptr (i.e. **arg_ptr - should be same as some_var): %d\n", **arg_ptr);
  }

int main()
  {
  int some_var = 5;
  int *ptr1;

  ptr1 = &some_var;

  printf("some_var: %d\n", some_var);
  printf("Address of some_var: %#p\n\n", &some_var);
  printf("Value stored in ptr1 (should be address of some_var): %#p\n", ptr1);
  printf("Address of ptr1 variable: %#p\n\n", &ptr1);
  ptrTest(&ptr1);
  }

发生了什么变化:

  1. 在printf( %d )中使用带符号的int格式,而不是无符号的格式( %u )。

  2. 打印指针时,在printf( %p )中使用的指针格式。

  3. ptrTest添加了代码,以跟随arg_ptr一直回到指针链的基本目标。

  4. 添加了代码以打印some_var的值

  5. 更改了输出的用语,以澄清显示的内容以及应该匹配的值。

新版本可以正确编译(HP-UX默认C编译器)。

运行新版本时,将输出以下输出:

some_var: 5
Address of some_var: 0x7fffecd0

Value stored in ptr1 (should be address of some_var): 0x7fffecd0
Address of ptr1 variable: 0x7fffecd4

Value stored in arg_ptr (points to ptr1): 0x7fffecd4
Value pointed to by arg_ptr (i.e. *arg_ptr - should be same as ptr1): 0x7fffecd0
Value pointed to by *arg_ptr (i.e. **arg_ptr - should be same as some_var): 5

现在,您可以沿着指针链前后移动,以查看哪个指针指向哪个值,以及它们如何链接在一起。

祝你好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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