C中的动态多维数组 [英] Dynamic Multidimensional array in C
问题描述
#define COLS 5
int(* rptr)[COLS];
int main(void)
{
int nrows = 10;
int row,col;
rptr = malloc(nrows * COLS * sizeof(int));
for(row = 0; row< nrows; row ++)
for(col = 0; col< COLS; col ++)
rptr [row] [col] = 17;
return 0;
}
这里,多维数组定义为int(* rptr)[COLS]然后动态链接到malloc(nrows * COLS * sizeof(int))。
现在的问题是指向如何工作,例如:如果指向地址开始从100,101,102 ...等
(假设int为了简单起见需要1个字节)
rptr [0]指向 - > 100
rptr [1]指向 - > 105
一旦malloc(nrows *),编译器会根据列大小相应地内部链接地址COLS * sizeof(int))被执行?
谢谢
>考虑这个普通数组分配:
int * a = malloc(sizeof(int)* 10);
类型int *当然是指向int的指针,sizeof(* a) == sizeof(int)。当我们做一个[3],它被转换为:
*(a + 3)
(假设sizeof(long)== sizeof(void *))取消引用地址:
(long)a + 3 * sizeof(* a)==(long)a + 3 * sizeof(int)
想想你的示例代码的方法是,类型int(* rptr)[COLS]是一个指向(静态,一个尺寸)数组大小COLS。换句话说,sizeof(* rptr)== COLS * sizeof(int)。然而,正如int *一样,我们可以分配这些固定大小的一维数组对象的数组。索引rptr [row]转换为:
*(rptr + row)
取消引用地址:
(long)rptr + row * sizeof(* rptr)==(long)rptr + row * COLS * sizeof(int)
结果类型为int [COLS],因此可以通过[col]重新编入索引。地址计算结果正是您想要的:
(long)rptr + row * COLS * sizeof(int)+ col * sizeof(int)
此解决方案在 http://c-faq.com/aryptr/dynmuldimary.html ,并且只有当列数(或一般来说,全部但第一个维度)在编译时是固定的。随着维数的增加,语法变得有点混乱。如果您需要在运行时动态确定多个维度,请参阅该页面了解其他策略。
reading a few articles on dynamic memory allocation for multidimensional arrays in c, I came across the following code snippet: (article link)
#define COLS 5
int (*rptr)[COLS];
int main(void)
{
int nrows = 10;
int row, col;
rptr = malloc(nrows * COLS * sizeof(int));
for (row = 0; row < nrows; row++)
for (col = 0; col < COLS; col++)
rptr[row][col] = 17;
return 0;
}
Here, a multidimensinal array is defined as int (*rptr)[COLS] and then dynamically linked to malloc(nrows * COLS * sizeof(int)).
Now the question is that how does the pointing work, eg: if the pointing address start from 100,101,102...etc
(assuming int takes 1 byte for simplicity)
rptr[0] points to -> 100
rptr[1] points to -> 105
Does the compiler internally link the address accordingly based on the column size as soon as malloc(nrows * COLS * sizeof(int)) is executed?
Thanks
Consider this ordinary array allocation:
int* a = malloc(sizeof(int) * 10);
The type "int*" is of course a pointer to an int, and sizeof(*a) == sizeof(int). When we do a[3], this is converted to:
*(a + 3)
which (assuming sizeof(long)==sizeof(void*)) dereferences the address:
(long)a + 3*sizeof(*a) == (long)a + 3*sizeof(int)
The way to think about your sample code is that the type "int (*rptr)[COLS]" is a pointer to a (static, one dimensional) int array of size COLS. In other words, sizeof(*rptr) == COLS * sizeof(int). However, just as with the "int *", we can allocate an array of these fixed-size one-dimensional array objects. The indexing "rptr[row]" gets converted to:
*(rptr + row)
which dereferences the address:
(long)rptr + row*sizeof(*rptr) == (long)rptr + row*COLS*sizeof(int)
The resulting type is "int [COLS]", so it can be indexed into again by "[col]". The address calculation ends up being precisely what you want:
(long)rptr + row*COLS*sizeof(int) + col*sizeof(int)
This solution is mentioned at http://c-faq.com/aryptr/dynmuldimary.html, and only works if the number of columns (or in general, all but the first dimension) is fixed at compile time. The syntax gets a bit messy as the number of dimensions increases. If you need more than one dimension to be determined dynamically at runtime, see that page for other strategies.
这篇关于C中的动态多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!