阅读这个问题:What is the difference between int* x[n][m] and int (*x) [n][m]?
正确答复说明了这一点:
int arr[2][3];
int (*p1)[2][3] = &arr; // arr decays to int(*)[3], so we need to take the address
int (*p2)[2][3] = new int[42][2][3]; // allocate 42 arrays dynamically
最后一行的评论说它分配了42个新数组。 这是如何运作的?有人可以向我解释一下吗?
谢谢!
我会回答这个问题,但我不能,所以新的问题是(:
答案 0 :(得分:2)
new int[3]
分配3个整数。现在new int[2][3]
分配2个数组,每个数组长度为3个整数。进一步扩展,new int[42][2][2]
分配42个数组,每个数组长度为2个数组,每个数组的长度为2个整数。声明实际上是一个递归的想法。
答案 1 :(得分:2)
好吧,上课时间。
multidemenional数组(在C ++中)是一块连续的内存。它分配全部元素,全部在一行中,然后通过组合索引访问器来访问它们。在本能。如果我有int x[2][3]
定义的数组,它实际上会将x[i][j]
转换为(&x[0][0]+i*3)[j]
。
sizoef(int [2] [3])== 24(4bytes / int * 2 * 3)
这种类型的数组通常被称为"静态"数组,因为必须在编译时分配数组的大小。
请注意,第一个大小对此查找无关紧要。这使得当REFERENCING这种类型的数组时,我们可以从类型中排除最小的大小。这使得以下两个函数都有效,并且可以处理上面声明的数组x:
int foo(int y[2][3]){ return y[1][1];}
int bar(int y[][3]){ return y[1][1];}
请注意,在此上下文中,sizeof(y)== sizeof(void *),但这是一个不同的问题。
静态数组的输入约定与您习惯的不同。部分类型信息在变量声明之后出现。这实际上也存在于typedef中:
typedef int a[4][20];
typedef int b[][20];
如果你想获取这种值类型的地址,那么你需要声明指向这个数组类型的指针。这可以通过以下方式完成:
int (*xptr)[2][3] = &x;
int (*var)[...]
表示var是指向int [2] [3]的指针。
当人们说C ++数组是指针时,他们并没有引用这种类型的数组:虽然我们可以将数据展平为一维数组,但数组比指针稍微复杂一些。
锯齿状数组(或动态数组)是以线性方式分配的单个连续内存块。这种类型的数组通常称为动态,因为在编译时不需要知道大小。
动态数组使用new或malloc分配(尽管你应该只在C ++中使用new)。这些类型的数组是严格指针。当我说int* a=new int[4]
时,我会分配4个整数:就是这样。
我们通过创建锯齿状数组来实现多重性,这些数组是指针数组。例如:
int** a = new int*[2];
for (int i = 0; i < 2; i++) { a[i]=new int[3];}
int arr[2][3];//
int (*p1)[2][3] = &arr; // arr decays to int(*)[3], so we need to take the address
int (*p2)[2][3] = new int[42][2][3]; // allocate a dynamic array (42 elements long) of int[2][3] (sizeof(int[2][3])==24, so this allocates 42*24 bytes!)
它基本上连续分配了43个int [2] [3]。所以它实际上提出了所有连续的内存(虽然为什么它需要是动态的而不是静态的超出我)。
就我个人而言,我的规则是多方位阵列而且会让人感到困惑,因为地狱&#34;现在只在本地环境中使用它们,但是每个都使用它们。