zoukankan      html  css  js  c++  java
  • 取得动态二维数组

     在C语言中,有内置的一维数组,二维数组等多维数组,也可以使用动态分配内存的方式,很容易的得到一个

    类似内置静态一维数组的动态数组(在这里我这么叫,也许并不存在这个定义 :)),但如何取得动态的二维

    数据组呢?如果理解了C语言中对于数组指针的访问方式,那么实现一个自己的二维数组是很简单的。

    下面首先理清一下一维数据指针的访问方式:

    假设定义有如下定义:

    #define DIMS 10

    int Arr1[DIMS]

    int *pArr1;

    学过C语言的人都知道可以如下访问数据中的每一个元素:

    Arr1[i] = xxxx;

    同样理解数据即指针也可以知道:

    pArr1 = Arr1;

    for (int i = 0; i < DIMS; ++i)

    {

        *pArr1 = xxxx;

        pArr1++;

    }

    这是一维的情况,那么二维呢?

    对于静态的二维数组,三维数组等等都是很方便的

    int Arr2[DIMS][DIMS];

    int *pArr2;

    for (int i = 0; i < DIMS; ++i)

    {

        for (int j = 0; j < DIMS; ++j)

        {

            Arr2[i][j] = xxxx; //访问数组单元

        }

    }

    pArr2 = Arr2;

    for (int i = 0; i < DIMS * DIMS; ++i)

    {

        *pArr2++ = xxxx; //访问数组单元,并下移指针

    }

    三维方式差不多,在C语言中,静态多维数据其实就是一个平面数据,C语言编译器会将数据访问的形式翻译成

    内存访问的形式。

    比如:

    一维: Arr1[i]   ----> *(Arr1 + (i * sizeof(Arr1[0])))

    二维: Arr2[i][j] ---> *(Arr2 + (i * sizeof(Arr2[0][0]) + n * sizeof(Arr2[0][0]))
           这里的n是二维数据的第二个下标的最大值

    三维:方式与上类似,以数组首地址开始,计算数据偏移。
    使用下标使用数组的方式,给人以清晰的感觉,两样可以增加写程序的复杂度,意味着可以减少错误的机率。
    在一些情况下,使用静态的二维数据有着它的局限性,在大小未知的情况下,使用静态数组就不方便,有某些

    情况下,会很耗费栈资源(静态数组在栈中分配),所以需要动态数组。对于一维的情况,可以像一维静态数

    据那样使用,可是对于多维数组,如果只是像静态数组那样分配元素所需要的空间,那么就无法使用下标方式

    访问数据。
    int *pArr1, **pArr2;
    pArr1 = (int*)malloc(sizeof(int) * DIMS);
    pArr2 = (int**)malloc(sizeof(int) * DIMS * DIMS);
    ...
    pArr1[i] = xxx;  //正确
    pArr2[i][j] = xxx; //错误

    这里二维为什么有问题呢?
    看一下反汇编指命:
    65:       pArr2[4][5] = 10;
    004011B8   mov         eax,dword ptr [ebp-4]  ;ebp-4是变量int **pArr2
    004011BB   mov         ecx,dword ptr [eax+10h]  ;10h = 4 * sizeof(int) = 4 * 4
    004011BE   mov         dword ptr [ecx+14h],0Ah  ;14h = 5 * 4
    这三行汇编指命是在VC6.0下生成的。
    第一行将变量地址存入EAX,然后将EAX移动到第四个偏移移到ECX,然后再取得第5个位置的数据,实现上这里

    可以如下解析:
    (pArr2[4])[5]
    下面来看一下静态二维数据的汇编代码:
    64:       Arr2[4][5] = 10;
    004011AE   mov         dword ptr [ebp-0DCh],0Ah  ;0DCh = [(10-1) - 4]*40 + (5-1)*4 - 4
    与上面相比,这里的方式有着很大的不同。静态二维数据是直接访问的,而动态方式,C语言并不认为是数组

    ,而是将其看成二次间接。
    有了以上的基础之后,我想读者一定很快就知道如何去实现一个动态二维数据了。
    首先建立一个行指针,指针行的数据,然后将行指针返回作为二维数据指针就OK了。
    下面给出示意图:

    简明实现动态二维指针

    这样就有一个问题,为申请一个二维数组,需要分配多次空间,这样会产生内存碎片,如是我想到了一种一次

    性分配内存的方法。示意图如下:

    一次性分配二维数组内存示意图
    最终实现代码如下:
    Dyn2DimArr.h
    -------------------------

    Dyn2DimArr.c
    -------------------------

    好了,二维动态数组已经实现了,会不会有人问三维的呢?我想实现原理已经在这里,问题应该不大了吧。

    为了方便使用,这里贴出测试代码,以可以使用的方式。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Solr简介
    儿童节快乐
    添加新的内容分类
    weka
    Junit测试样例
    Linux MySQL单实例源码编译安装5.5.32
    perconatoolkit 工具集安装
    Linux MySQL单实例源码编译安装5.6
    MySQL 开机自启动
    mysql5.6之前需要账号的安全加固
  • 原文地址:https://www.cnblogs.com/yin138/p/4902270.html
Copyright © 2011-2022 走看看