为什么有人需要指向指针的指针?

3
例如,为什么需要char **myVariable;?如果指针只是内存中的地址,那么它指向一个带有指向char地址的指针的地址与只指向一个char地址的地址有什么区别呢?
在汇编中,这会像什么样子?
LDR R3, =myVariable
LDR R2, =[R3]
LDR R1, =[R2]
LDR R0, =[R1]

在这里,单个指针将会被使用

LDR R1, =myVariable
LDR R0, =[R1]

现在R0保存了数值吗?显然这种方式更快。


7
char **argv 表示一个指向字符指针的指针,用于存储命令行参数。 - user541686
1
  1. 对于链表,其中一个函数是分配内存。
  2. 当您有一个以空字符结尾的字符串数组时?
- Koushik Shetty
2
@CareyGregory 建设性的回答 - Celeritas
7个回答

11

如果您想通过函数修改指针的值,您将需要通过引用将指向该指针的地址传递给函数。因此,您需要将指向指针的指针作为参数。

示例:

int main()
{
  int num=0;
  int *p = #
  // This function passes the pointer by value. 
  //So when function returns, *p points to same place
  fn(p);

  // This function will actually change where the pointer points to as 
  // it was passed by reference
  fn2(&p);
}
void fn(int *ptr)
{
    static int i=1;
    ptr = &i;
}
void fn2(int **ptr)
{
    static int j=1;
    *ptr = &j;
}

1
+1 这是一个实际的现实生活例子,是正确答案之一。 - user529758
5
虽然为此目的提供参考文献会更好,但由于我们正在讨论C++,因此我将进行翻译。 :P - cHao
我想指出的是,通常可以使用指向指针的引用来处理这种情况。唯一的例外是当您希望有轻松传递NULL以表示您不关心该输出值的选项时。 - Mike Woolf

10

如果您有一个指针表,则指向该表的指针将具有“指向指针”的类型。


3
int main ( int argc, char **argv )

一个字符串数组。

当然它会更慢,因为你需要在中间多做一步操作,但是如果没有这一步操作,你就无法拥有指针的数组/表/列表。你只能拥有一个。


2
上面的回复已经解答了你问题的第一部分。对于第二部分的问题,"如果它是指向一个指向字符地址的地址的指针,与仅指向字符地址的指针有什么区别?"
虽然从内存布局上来说,你所说的是正确的,但C/C++会根据指针的类型处理指针。 当你执行指针++时,它会将指针按照它指向的数据类型的大小进行增量操作。 如果它是指向整数的指针,则增加4;如果它是指向字符的指针,则增加1;如果它是指向大小为20的结构体的指针,则增加20。

1

当你需要处理指针的存储和操作时,就需要使用指向指针的指针;例如:更改底层指针的内容。例如:

int i = 0, j = 1;
int* p = &i;
int** pp = &p;

现在您想让p指向j而不是i,那么您可以这样做:
*pp = &j;  // equivalent to `p = &j;`

这只是用来解释的。在实际世界中,当你处理函数时需要使用它。

void Destroy (int** pp) {  // for any int pointer
  delete[] pp;  // deallocate the memory
  *pp = 0;  // set the pointer to 0, so that it's not dangling
}

并将其用作:

int* pi = new int[30];
...
Destroy(&pi); // `pi` is now pointing to 0

但在C++中,您仍然有更好的选择,即"指针引用"。它基本上做的是相同的事情,但可读性更好。

void Destroy (int*& p) {  // for any `int` pointer 
  delete[] p;  // destroy the memory
  p = 0;  // Null out the same pointer which was actually passed
}

使用如下:

Destroy(pi);  // no need to pass address

1
按引用传递更易于调用并增加了一定程度的保护。然而,由于按引用传递几乎不可避免地实现为按指针传递,因此在性能方面,指针引用和指向指针的指针基本上是相同的。 - David Hammen

0
  1. 假设您有一个指针,指针的值很重要。例如,指针指向数组中的一个元素。然后您使用该指针调用函数,并将其视为输入/输出参数,以便函数可以修改它。在这种情况下,可以通过增加一层间接性并将指针的指针传递给函数来实现此目的,以便它可以更改指针。
  2. @Lindyracer的:指针数组。
  3. 在某些操作系统中,如果您获得了“全局”指针,则会使用双重间接性(通常将其作为typedef定义的类型获取)。背后的原因是,如果存储双重指针,则内存管理器可以自由更改由该双重指针指向的指针,以便它可以移动和整理等。

还有许多其他内容。


在C++中,你通常会为此目的选择引用。 - cHao
这是正确的@cHao。在现代C++中,你理想情况下不会看到太多**s。 - Csaba Toth

0

首先,因为在语言上完成是有意义和必要的,不留下未定义的领域,以确定表达式&p的含义,其中p是指针?

而且这似乎也非常方便。以下是Linus Torvalds的答案。 使用指针从单链表中删除项目


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