所以我一直试图更多地理解指针而且我遇到了这个:
double **DPtr; // just for example
我已经读过它可以用来指向一个多维数组,但是在我使用单个间接符号(*
)之前我无法使它工作。
所以,如果我不能对多维数组使用双重间接,那它的用途是什么?
我试图找到答案,但我没有运气。
提前感谢您提供给我的任何信息! :)
答案 0 :(得分:5)
你的问题不太清楚。您可以使用double**
创建自己的二维数组,并进行大量手动记账:
const size_t dim1 = 10, dim2 = 20;
double **arr;
arr = new double*[dim1];
for (size_t idx = 0; idx < dim1; ++idx) {
arr[idx] = new double[dim2];
}
double[4][5] = 3.14;
对于每个“主要”索引,每个“辅助”数组的大小可能都不同,所以数组甚至可能是“锯齿状”。
然而,它实际上是一个指向数组的指针数组,它不是一个真正的二维数组,因为它在内存中不是连续的。如果您改为创建一个真正的二维数组:
double arr[dim1][dim2];
然后没有办法安全地将其转换为可解除引用的double **p
。原因是地址p[2]
处的内存存储指向double
的指针,而地址arr [2]处的存储器存储double
(double
数组中的第一个存储器} S)。
修改强>
基于您在注释中表达的“主要问题”:双重间接在C ++中不如在C中有用.C没有引用,因此如果您希望函数提供指针类型的输出参数,那么必须采取双指针。例如:
void allocate(int style, char **arr)
{
switch (style) {
case 0: *arr = malloc(100); break;
case 1: *arr = malloc(200); break;
default: *arr = malloc(300); break;
}
}
int main(void)
{
char *a;
allocate(1, &a); //this way, allocate can modify a
}
在C ++中,你可以通过引用传递指针来实现相同的目的:
void allocate(int style, char * &arr)
{
switch (style) {
case 0: arr = new char[100]; break;
case 1: arr = new char[200]; break;
default: arr = new char[300]; break;
}
}
int main()
{
char *a;
allocate(1, a); //a is passed by reference, allocate can modify it
}
一般情况下,尝试避开C ++中的原始指针并直接使用对象,或者如果需要动态内存则使用智能指针。双向间接指针甚至更罕见。
答案 1 :(得分:2)
好
double **DPtr;
定义指向double的指针。这可以有不同的用途,特定于您的问题,它可以用于2d数组的double。但请注意,
double* A = new double[10][10]
定义一个长度为100的内存块,而不是一个双指针数组,并且每个块都包含十个双精度数。要拥有一个“真正的”二维数组,你可以做这样的事情
double** A2d = (double*)[10];
for(int i=0; i<10;i++){
A2d = new double[10]
}
这将创建一个包含10个数组的10个数组的数组。 请注意,您可以以相同的方式访问这两种类型的2d数组,例如 A [1] [5] 对两者都有用。真正的2d阵列将特别有用,二阶阵列具有不同的大小。但总的来说,我建议使用单指针变体。
答案 2 :(得分:1)
首先,您可以将它用于2D数组(动态分配)。
例如:
double** array;
array = new double*[10];
for(unsigned int i = 0; i < 10; i++){
array[i] = new double[20];
}
创建一个10x20 2D数组,可以按照以下方式访问
//Classic syntax with subscript operator
double d1 = array[2][4];
//Obfuscate syntax using pointer arithmetics
double d2 = *(*(array+2)+4);
您正在使用指针数组(可以自己用作数组)。尽管如此,这仍然是非常实际的,并且是美国的(在许多情况下原始指针是不安全的),std::array
或std::vector
应该是首选。
但它也可以简单地用作指向指针的指针(它可以比 double 指针更远)。
例如:
int var = 10;
int *var_ptr= &var;
int **var_dbl_ptr = &var_ptr;
std::cout << **var_dbl_ptr << std::endl;
//Prints 10
答案 3 :(得分:1)
“指向对象的指针”本身就是一个对象,因此它本身可以“指向”......指向(对象的一个指针)的指针。
类似地,对象的数组本身就是一个对象,它可以是“(对象的数组)数组的一部分”
现在,作为“数组的名称”也是“第一个元素的地址”,* a和a [0]之间的表达存在实质等价(因此*(a + n)和a [ N])。
因此,您可以在double** pp
这样的表达式中使用pp[3][4] = 3.14;
但是数组和指针之间的机制是不同的:
数组看起来像
_ _ _ _ _
_ _ _ _ _
_ _ _ _ _
Wile双间接看起来像
_ --> _ --> _ _ _ _
_ --> _ _ _ _ _ _
_ --> _ _ _
在第一种情况下,有一个物体重复5次以产生重复三次的“宽物体”。
在第二种情况下,有一个“指向指针的指针”指向“三个指针组”,每个指针指向一组独立的对象(具有独立的大小)。