我正在编写代码来了解当指针作为函数中的参数传递时会发生什么。
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);
}
改变了什么:
%d
)中使用signed int格式而不是unsigned格式(%u
)。%p
)中使用指针格式。ptrTest
的代码,一直跟随arg_ptr
回到指针链的基本目标。some_var
的值新版本编译时没有错误(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
现在,您可以向前和向后跟踪指针链,以查看哪个指针指向哪个值,以及它们如何链接起来。
祝你好运。