[英]how does p become a 2-D array after the call to malloc?
以下代码段使用malloc
函数声明了4 X 10的二维数组
/* Declare a pointer to an array that has 10
ints in each row. */
int (*p)[10];
register int i, j;
/* allocate memory to hold a 4 x 10 array */
p = malloc(40*sizeof(int));
但是我不明白p
如何变成二维数组。 最初,p被声明为指向int的指针数组。 调用malloc之后会发生什么? 我无法理解。
价值40 int的内存保留给指针p。 p指向他的记忆块。 碰巧,p选择将此内存组织为10个相等的部分,每个部分恰好持有4个整数的价值。
那是如果此代码实际上是正确的。 这时我的C非常生锈。
在C语言中,尽管看起来非常相似,但指针和数组却并不相同。 在这里, p
是“指向10个整数的数组的指针”的类型。 您将其用作“指向10个整数的4个数组的数组的指针”,它是一个内存块(唯一的指针是最外面的指针)。 它基本上是一个动态分配的int[4][10]
。
阅读这些定义的诀窍是要意识到它们的书写方式与您使用该项的方式相同。 如果你有:
*x[10];
首先应用数组下标, 然后取消指针的引用。 因此,如果您定义int *x[10]
则它是一个指针数组。 如果使用括号覆盖正常优先级,则可以首先取消对指针的引用,因此可以使用指向数组的指针。
令人困惑? 情况变得更糟。 在函数参数中,函数参数的最外层数组将转换为指针。
int *p[10]; // array of 10 pointer to int
int (*p)[10]; // pointer to array of 10 ints
void foo(int *p[10] /* pointer to pointer to int */);
void foo(int (*p)[10] /* pointer to array of 10 ints */);
此外,使用数组时,数组会转换为指针。
int x[10]; // array of 10 int
sizeof(x); // 10 * sizeof(int)
int *y = x; // implicitly converts to a pointer to &x[0]!
sizeof(y); // sizeof(int *)
这意味着您可以为数组数组分配内存,然后将其隐式转换为指向数组的指针,然后将其用作数组数组!
无论如何,这都是非常令人困惑的,所以请不要在生产代码中使用它-至少在没有弄清楚typedef的情况下:
typedef int vector[3];
vector *array_of_vectors; // actually a pointer to a vector,
// but you can use it as an aray to a vector if enough
// memory is allocated
首先,一些背景信息:
除非它是sizeof
, _Alignof
或一元&
运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,否则将转换类型为“ T
N元素数组”的表达式(“ decays” )到“ pointer to T
”类型的表达式,其值是数组中第一个元素的地址。 例如,给定数组
int a[10];
随时表达a
出现在代码,它的类型将从“的10个元素的数组被转换int
”到“指针int
”,或int *
, 除了像箱子sizeof a
, _Alignof a
,并&a
。 如果我们有T的2D数组,例如
int a[10][10];
表达a
将从类型“的10个元素的数组的10个元素的数组被转换int
为”指针的10个元素的数组“ int
”,或int (*)[10]
看起来很熟悉?这类型的指针p
)。
如果我们要动态分配类型为T
的N元素数组,我们可以编写类似
T *p = malloc(N * sizeof *p);
sizeof *p
等效于sizeof (T)
。 在这种特定情况下,类型T
是“ int
10个元素的数组”或int [10]
。 我们想分配4个这样的数组,所以我们可以写
int (*p)[10];
p = malloc(4 * sizeof *p);
这将为int
4个10元素数组分配空间,并将结果分配给p
。 ( sizeof *p == sizeof (int [10])
)。
那么这如何成为2D阵列呢?
请记住,表达式a[i]
等效于*(a + i)
; 我们发现的地址i
“个类型的元件 T
以下a
和解除引用的结果。 在这种情况下, p[i]
给出了紧随p
的int
p
i
个10元素数组的地址。 由于我们在下标操作中取消了对指针的引用,因此表达式p[i]
的类型为“ int
10元素数组”。 因此,我们可以再次下标该表达式并得到p[i][j]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.