为什么指针指针?

时间:2014-03-05 09:23:48

标签: c++ pointers

一个非常普遍的问题:我想知道为什么我们使用指针指针? 指向指针的指针将保存指针的地址,而指针又指向另一个指针。但是,即使使用单个指针也可以实现这一点。

考虑以下示例:

{
  int number = 10;
  int *a = NULL;

  a = &number;

  int *b = a;

  int *pointer1 = NULL;
  pointer1 = b;  //pointer1 points to the address of number which has value 10

  int **pointer2 = NULL;
  pointer2 = &b;  //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??

  return 0;
}

7 个答案:

答案 0 :(得分:3)

我认为你回答了自己的问题,代码是正确的,你评论的不是。

int number = 10;是值

int *pointer1 = b;指向保存int号的地址

int **pointer2 = &b;指向保存int号地址的地址

你看到这里的模式吗?

address = * (single indirection)

address of address = ** (double  indirection)

答案 1 :(得分:2)

首先,指针不指向值。它指向内存位置(即它包含一个内存地址),而后者又包含一个值。所以当你写

pointer1 = b;

pointer1指向与变量number的b相同的内存位置。之后是你执行

pointer2 = &b;

然后pointer2指向b的内存位置,其中不包含10,但变量的地址为number

答案 2 :(得分:1)

以下表达式为真:

*pointer2 == b 
**pointer2 == 10 

以下不是!

*pointer2 == 10 

当您想要更改指针指向函数外部的内容时,指针指针非常有用。例如

void func(int** ptr)
{
    *ptr = new int;
    **ptr = 1337;
}

int main()
{
    int* p = NULL;
    func(&p);
    std::cout << *p << std::endl;   // writes 1337 to console
    delete p;
}

一个愚蠢的例子,展示可以实现的目标:)只用一个指针就无法完成。

答案 3 :(得分:0)

您的假设不正确。 pointer2不指向值10,而是指向b的(地址)。使用pointer2运算符取消引用*会生成int *,而不是int

您需要指针指针,原因与首先需要指针的原因相同:在函数调用中实现pass-by-reference参数,实现数据结构之间的数据共享等等。

答案 4 :(得分:0)

一个简单的例子是矩阵的实现(它是一个例子,它不是用C ++实现矩阵的最佳方法)。

int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
  M[i] = new double[ncols];
M[3][7] = 3.1416;

答案 5 :(得分:0)

你很少在普通的C ++代码中看到这个构造,因为C ++有引用。它在C中用于“通过引用传递:”

int allocate_something(void **p)
{
  *p = malloc(whatever);
  if (*p)
    return 1;
  else
    return 0;
}

等效的C ++代码将使用void *&p作为参数。

不过,你可以想象,例如像这样的资源监视器:

struct Resource;

struct Holder
{
  Resource *res;
};

struct Monitor
{
  Resource **res;

  void monitor(const Holder &h) { res = &h.res; }
  Resource& getResource() const { return **res; }
}

是的,这是设计的,但想法就在那里 - 它将保持指向存储在持有者中的指针,并且即使持有者的res指针发生变化也能正确返回该资源。

当然,这是一个等待发生的悬挂式解除引用 - 通常,你会避免像这样的代码。

答案 6 :(得分:0)

在这样的构造中,有了更大的数据结构。 C语言中的OOP由于缺乏实现具有结构的方法的可能性,因此方法明确传递了c ++ this参数。此外,一些结构由指向一个特别选择的元素的指针定义,该元素在方法的全局范围内保存。

所以当你想通过整个结构时,例如一个树,并且需要更改根或列表的第一个元素,您将一个指向指针的指针传递给这个特殊的root / head元素,这样您就可以更改它。 / p>

注意:这是使用c ++语法进行方便的c风格实现。

void add_element_to_list(List** list, Data element){
  Data new_el = new Data(element); // this would be malloc and struct copy
  *list = new_el; //move the address of list, so it begins at new element
}

在c ++中有参考机制,你通常可以用它实现几乎任何东西。它基本上使得指针的使用在c ++中已经过时了,至少在许多情况下是如此。你也可以设计对象并对它们进行处理,而且所有东西都隐藏在引擎盖下。

最近还有一个很好的问题“为什么我们在c ++中使用指针?”或类似的东西。