在C语言中什么时候应该使用双重间接?谁能举个例子解释一下吗?
我所知道的是双间接是指向指针的指针。为什么我需要指向指针的指针?
在C语言中什么时候应该使用双重间接?谁能举个例子解释一下吗?
我所知道的是双间接是指向指针的指针。为什么我需要指向指针的指针?
当前回答
例如,如果您想随机访问不连续的数据。
p -> [p0, p1, p2, ...]
p0 -> data1
p1 -> data2
——用C
T ** p = (T **) malloc(sizeof(T*) * n);
p[0] = (T*) malloc(sizeof(T));
p[1] = (T*) malloc(sizeof(T));
存储一个指针p,它指向一个指针数组。每个指针指向一段数据。
如果sizeof(T)很大,则可能无法分配sizeof(T) * n字节的连续块(即使用malloc)。
其他回答
一个原因是你想要改变传递给函数的作为函数参数的指针的值,要做到这一点,你需要指针指向指针。
简单地说,当你想在函数调用之外保留(或保留)内存分配或分配的变化时,使用**。(因此,传递带有双指针arg的函数。)
这可能不是一个很好的例子,但会告诉你基本的用法:
#include <stdio.h>
#include <stdlib.h>
void allocate(int **p)
{
*p = (int *)malloc(sizeof(int));
}
int main()
{
int *p = NULL;
allocate(&p);
*p = 42;
printf("%d\n", *p);
free(p);
}
简单的例子,你可能已经见过很多次了
int main(int argc, char **argv)
在第二个参数中有它:指向char的指针的指针。
注意,指针表示法(char* c)和数组表示法(char c[])在函数参数中是可互换的。所以你也可以写char *argv[]。换句话说,char *argv[]和char **argv是可互换的。
上面所代表的实际上是一个字符序列数组(在启动时给予程序的命令行参数)。
有关上述函数签名的更多详细信息,请参见此回答。
我今天看到了一个很好的例子,从这篇博客文章,我总结如下。
假设您有一个链表中节点的结构,可能是这样
typedef struct node
{
struct node * next;
....
} node;
现在您想实现一个remove_if函数,它接受删除条件rm作为参数之一,并遍历链表:如果一个条目满足该条件(例如rm(entry)==true),它的节点将从链表中删除。最后,remove_if返回链表的头(可能与原始头不同)。
你可以写信
for (node * prev = NULL, * curr = head; curr != NULL; )
{
node * const next = curr->next;
if (rm(curr))
{
if (prev) // the node to be removed is not the head
prev->next = next;
else // remove the head
head = next;
free(curr);
}
else
prev = curr;
curr = next;
}
就像你的for循环。这里的信息是,如果没有双指针,您必须维护一个prev变量来重新组织指针,并处理两种不同的情况。
但是使用双指针,你实际上可以写
// now head is a double pointer
for (node** curr = head; *curr; )
{
node * entry = *curr;
if (rm(entry))
{
*curr = entry->next;
free(entry);
}
else
curr = &entry->next;
}
你现在不需要一个prev,因为你可以直接修改什么prev->next指向。
为了使事情更清楚,让我们稍微跟随一下代码。拆卸过程中:
如果entry ==* head:它将是*head (==*curr) =* head->next - head现在指向新标题节点的指针。您可以通过直接将head的内容更改为一个新的指针来实现这一点。 如果entry != *head:类似地,*curr是prev->next所指向的,现在指向entry->next。
无论哪种情况,您都可以使用双指针以统一的方式重新组织指针。
字符串是使用双指针的一个很好的例子。字符串本身是一个指针,所以任何时候你需要指向一个字符串,你就需要一个双指针。
添加到Asha的响应,如果你使用单个指针指向下面的例子(例如alloc1()),你将失去对函数内部分配的内存的引用。
#include <stdio.h>
#include <stdlib.h>
void alloc2(int** p) {
*p = (int*)malloc(sizeof(int));
**p = 10;
}
void alloc1(int* p) {
p = (int*)malloc(sizeof(int));
*p = 10;
}
int main(){
int *p = NULL;
alloc1(p);
//printf("%d ",*p);//undefined
alloc2(&p);
printf("%d ",*p);//will print 10
free(p);
return 0;
}
发生这种情况的原因是在alloc1中,指针是按值传入的。因此,当它被重新分配给alloc1内部的malloc调用的结果时,更改不属于不同作用域中的代码。