这两种声明指针的方法有什么区别?
看一下这个代码片段:
int i = 10;
int *pi = &i;
int **ppi = π // first declaration
int *api = pi; // second declaration
printf("i's value is: %d\n",i);
printf("pi's value is: %d\n",*pi);
printf("ppi's value is: %d, at the address: %d\n",**ppi);
printf("api's value is: %d, at the address: %d\n",*api);
输出
$ ./test
i's value is: 10
pi's value is: 10
ppi's value is: 10, at the address: 2686760
api's value is: 10, at the address: 2686760
那么,在这两种指针到指针的声明中,哪种方式(也许)更可取,这两种方式之间有什么技术差异吗?
Have a look at this code snippet:
int i = 10;
int *pi = &i;
int **ppi = π // first declaration
int *api = pi; // second declaration
printf("i's value is: %d\n",i);
printf("pi's value is: %d\n",*pi);
printf("ppi's value is: %d, at the address: %d\n",**ppi);
printf("api's value is: %d, at the address: %d\n",*api);
Output
$ ./test
i's value is: 10
pi's value is: 10
ppi's value is: 10, at the address: 2686760
api's value is: 10, at the address: 2686760
So which way is (perhaps) more preferrable in those 2 declarations of pointer to pointer, and is there any technical difference between those two?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从技术上讲,您只声明了一个指针到指针。
第二个声明只是一个指针,在分配时,它会获取第一个指针 pi 地址的副本。
您可以通过以下方式证明这一点;在您的测试代码之后,添加以下内容:
输出将是:
当您更改 pi 的值(它指向的内容)时,取消引用 ppi 将反映更改,因为它指向
pi
,但由于api
在更改之前只是作为pi
的副本制作的,因此它将继续指向i< /代码>。
Technically, you've only declared one pointer-to-pointer.
The second declaration is just a pointer which, when assigned, gets a copy of the first pointer
pi
's address.Here's how you can prove it; after your test code, add this:
The output will be:
When you change the value of
pi
(what it points to), dereferencingppi
will reflect the changes, as it points topi
, but becauseapi
was just made as a copy ofpi
before it changed, it will continue pointing toi
.第二个 (
api
) 没有声明指向指针的指针。它创建一个指向 int 的指针,并使用另一个指向 int 的指针的值对其进行初始化。The second one (
api
) doesn't declare a pointer to pointer. It creates a pointer to int, and initializes it with the value of another pointer to int.您的最后两个 printf(
ppi
和api
)缺少第二个参数,因此它会打印该参数所在堆栈中的任何内容应该是(使用适当的警告进行编译会发现这一点)。api
不是指向指针的指针,它是指向int
的指针,与pi
相同。声明指向指针的指针(忽略空格和括号样式)的唯一方法是type **var
。Your last two
printf
s (ppi
andapi
) are missing their second argument, so it's printing whatever happens to be in the stack where said argument should be (compiling with appropriate warnings would have caught this).api
is NOT a pointer to a pointer, it's a pointer to anint
, same aspi
. The ONLY way to declare a pointer to a pointer (ignoring spacing and parentheses styles) istype **var
.类型定义了如何交互数据的语义,例如,您不应该将指向 int 的指针直接分配给指向 int 指针的指针。但是,您可能想知道使用 ** 类型的用例。
举个例子,看看我写的这段代码:
我的机器上的输出:
有函数和标准库以及其他地方,它们采用指向类型指针的指针。只要 ** 的参数不是 const 限定的,就表明该值可以更改,并且它可能也可能不指向相同的分配内存。在我的示例中,我删除了旧指针,但这是您需要注意的特定功能。此外,如果调用者负责删除返回的任何新内存,也可能是特定于函数的,因此请阅读您看到的使用这些函数的任何函数的文档,并确保您记录了您写得好的任何函数。
The types defined the semantics of how you interact the data, you should not ever assign a pointer to int directly to a pointer to a pointer of an int, for example. However you might be wondering a use case of using a ** type.
For an example, look at this code I wrote:
The output on my machine:
There are functions and the standard library, and elsewhere, that take a pointer to a pointer of a type. As long as a parameter of ** is not const qualified, it indicates that the value can be changed and it may, or maynot point to the same allocated memory. In my example I deleted the old pointer, but that is function specific you need to watch out for. Also, if the caller is responsible to delete any new memory returned could also be function specific, so read the documentation of any functions you see that use these and make sure you document any that you write well.