为什么指针对指针
Why pointer to pointer?
一个非常普遍的问题:我想知道为什么要使用指针对指针?指向指针的指针将保存一个指针的地址,而该指针又将指向另一个指针。但是,这甚至可以通过使用单个指针来实现。
考虑以下示例:
{
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;
}
我认为您回答了自己的问题,代码是正确的,您所评论的不是。
int number = 10;
是值
int *pointer1 = b;
指向保存int号的地址
int **pointer2 = &b;
指向保存整数地址的地址
你看到这里的图案了吗??
address = * (single indirection)
address of address = ** (double indirection)
以下表达式为true:
*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;
}
一个愚蠢的例子展示了可以实现的目标:)只有一个指针是做不到的。
首先,指针不指向值。它指向内存位置(即它包含一个内存地址),而该内存位置又包含一个值。所以当你写的时候
pointer1 = b;
CCD_ 4指向与作为变量CCD_ 5的b相同的存储器位置。现在你执行
pointer2 = &b;
然后pointer2
指向b
的存储位置,该存储位置不包含10
,而是变量number
的地址
您的假设不正确。pointer2
不指向值10,而是指向指针b
的(地址)。使用*
运算符取消对pointer2
的引用将生成int *
,而不是int
。
您需要指向指针的指针,原因与您首先需要指针的原因相同:在函数调用中实现引用传递参数,在数据结构之间实现数据共享,等等
在c中,对于更大的数据结构,这样的构造是有意义的。在C中的OOP中,由于缺乏在结构中实现方法的可能性,这些方法具有显式传递的C++this
参数。此外,一些结构是由指向一个特别选择的元素的指针定义的,该元素保存在方法的全局范围中。
因此,当你想传递整个结构,例如一棵树,并且需要更改根或列表的第一个元素时,你可以将一个指针对指针传递给这个特殊的root
/head
元素,这样你就可以更改它
注意:这是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++实现矩阵的最佳方式)。
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;
您很少在普通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
指针发生变化,也会正确返回该资源。
当然,这是一个悬而未决的取消引用等待发生——通常,你会避免这样的代码。
- 为什么使用 "this" 指针调用派生成员函数?
- 为什么++(*p)更改指针值
- C++取消引用指针.为什么会发生变化
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 为什么指针不写入类的地址?
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- 非类型指针和引用模板参数,以及在编译时如何/为什么解析它们.c++
- 为什么要增加导致崩溃的指针
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 共享指针:为什么没有双免费
- 指向2D数组的指针(为什么起作用)
- 函数指针 - 为什么,什么时候我可以没有
- C++ 函数指针 -- 为什么会这样
- 不支持在c或c++中添加两个指针.为什么?
- 无效的指针-为什么
- 模板基类可以存储指向派生但不能存储对象的指针 - 为什么
- 在信号代码中将整数转换为函数指针-为什么这样做?
- 指向结构体作为函数参数的指针-为什么不更新其值