一个非常普遍的问题:我想知道为什么我们使用指针指针? 指向指针的指针将保存指针的地址,而指针又指向另一个指针。但是,即使使用单个指针也可以实现这一点。
考虑以下示例:
{
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;
}
答案 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 ++中使用指针?”或类似的东西。