指针指向指针的必要性

10
存储指针地址需要什么?
  int a = 2;
  int *p = &a;
  int **q = &p;

有什么实际用途吗?实时应用。


你要找的答案在这里:http://www.codeproject.com/Articles/4894/Pointer-to-Pointer-and-Reference-to-Pointer。 - Santhosh Pai
5
术语“double pointer”是具有误导性的,请将其更改为“指向指针”的术语 :) - 0decimal0
1
现在为什么要被搁置?这并不是一个很糟糕的问题。 - Pranit Kothari
1
@Gops AB:+1 没有必要暂停。 - Pranit Kothari
打开链接了解“双指针和指向指针”的相关内容(http://codepad.org/ZlMenjn2),现在您可以随时删除您的未回答问题(http://stackoverflow.com/questions/18308775/double-pointer-and-pointer-to-pointer)并恢复您的存储库,这是我最喜欢的 Stack Overflow 功能 :) - Grijesh Chauhan
5个回答

24

在 C 语言中,你可以传递一个对象的 "值" 或者 "地址"。如果在函数调用时传递的是值,那么在函数内部做出的更改将不会反映在调用的地方。如果要反映更改,你需要传递对象的地址,例如:

void insert(node* head){
   head->data = 10;    // address(or head) is still same 
}

在这里,"object"指的是任何类型的int、char或struct,例如node

在上面的例子中,如果你改变由head指针引用的地址的值,那么data中的更改将被反映。

但是,假设你想改变列表中的head本身(例如将新节点插入为第一个节点)。

void insert(node* head){
   head = malloc(sizeof(head));  // head changed 
   head->data = 10;
}

由于函数中的head与调用位置的head不同,因此值在调用位置不会反映。

你有两个选择,要么return head,要么使用指向指针(但记住只能返回一个值)。

使用指向指针:

void insert(node** head){
   (*head) = malloc(sizeof **head);   
   (*head)->data = 10;
}

现在更改将反映出来!

关键是,如果地址是您的值(需要更新地址),那么您需要使用地址的指针或者我应该说是指向指针的指针,以便在调用位置反映出更改。

正如您的问题所在,指针到指针的需求还有另一个地方,即字符串数组动态二维数组,并且为了同样的用途,您可能需要指向指针的指针,例如动态矩阵的字符串或3D字符数组

也可以阅读这篇文章:指针到指针,我只是找到了一个例子告诉您。


1
Cauhan: +1。非常好的答案。在链表中我也使用了相同的方法。 - Pranit Kothari
1
这恰好回答了所问的问题,尽管它只是其使用的一个方面,但仍然值得一加 :) - 0decimal0
1
应该是(* head),而不是(head *)。 - Asaf
1
@GrijeshChauhan:是的,有的——以C#为例。请参见http://pobox.com/~skeet/csharp/parameters.html。 - Jon Skeet
1
@GrijeshChauhan:是的,我相信C++有按引用传递的功能,但我不想过多地宣称,因为我已经很久没有使用C++了,也不知道其中的技术细节。 - Jon Skeet
显示剩余11条评论

12

**只是指向指针的指针。所以,*p包含一个p的地址,而p**包含一个p*的地址,这个p*又包含一个p对象的地址。

**用于在函数外部保留内存分配或赋值

还可以查看这篇文章

示例:

void allocate(int** p)
{
  *p = (int*)malloc(sizeof(int));
}

int main()
{
  int* p = NULL;
  allocate(&p);
  *p = 1;
  free(p);
}

@Rahul Tripathi:他在谈论实际应用吗? - Pranit Kothari
@pranitkothari:更新了我的答案,并附上了实际用途。希望现在有意义了;) - Rahul Tripathi

4

Does

int main (int argc, char** argv) { ... }

看起来很熟悉吗?


1
是的,我认为我们最常需要指向指针的地方就是在代码中使用"+"运算符时,这个例子非常有用并且被广泛地使用。 - Grijesh Chauhan

3

如果你想在另一个函数中分配Nth顺序指针,你应该使用(N+1)th顺序指针。例如:

void allocate_matrix(int ***ptr, int x, int y);

让我们分配一个矩阵:

int **matrix:
allocate_matrix(&matrix, 5, 5);

1

其中一个用途是在函数内部更改指针的值。例如:

#include <stdio.h>

void swapStrings(const char **strA, const char **strB)
{
    const char *tmp = *strB;
    *strB = *strA;
    *strA = tmp;
}

int main()
{
    const char *a;
    const char *b;
    a = "hello";
    b = "world";
    swapStrings(&a,&b);
    // now b points to "hello" and a points to "world"
    printf("%s\n", a);
    printf("%s\n", b);
}

输出:

world
hello

1
你可以使用realloc来增加已分配的内存。 - Gibbs
Rahul,我们在什么情况下需要在函数调用之外保留内存。 - Gibbs
而且还要保留原始值,不要破坏它们。 - cHao
@GopsAB 这很难这样回答。如果你遇到这种情况,你会看到它。 简而言之,每当您想指向指向其他地方的东西时,都需要它。也许看看指针数组;它们也会衰变成指向指针的指针。 - glglgl
好的,那是一个糟糕的例子。 - Wayne Uroda
或者查看main(int argc, char ** argv) - glglgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接