C中的动态多维数组 [英] Dynamic Multidimensional array in C

查看:138
本文介绍了C中的动态多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆