2维数组与动态创建2维数组。

2维数组与动态创建2维数组。

一维数组的逻辑概念是一组数据,由下标指向。在内存分配上是连续的
二位数组的逻辑概念是一个表,由行,列来指向。数据的存储方式通常是按行存储的。
  在内存的分配上要看这个二维数组元素到底是什么结构.
例如: a 是一个2维静态数组,,则int a[i][j],  逻辑上指第i行的第j个数据。那么其数据地址是如下计算的

举例: int a[2][3], 固定的2行3列静态数组

则:&a[i]=a+i*3*sizeof(int) // 地址只是一个计算方法,并不实际用内存存放该地址

则: &a[i][j] = a+i * 3*sizeof(int) +j *sizeof(int) , 数据在内存上是连续的.

例如 a 是一个2维指针,int **a, 则a[i]是一个一维指针,

则: &a[i]=a+i*sizeof(int *)   // 注意,存放的是指针!

则: &a[i][j] = (*&a[i]) + j * sizeof(int *) .

就是说先取出a[i]地址处的内容为基地址,再加上j个元素的偏移地址

由以上分析知道,&a[i][j]内存地址计算方法,根据a的类型不同,是静态数组?还是指针?将有不同的计算方法.
------------------------------------------------------------
静态2维数组示例:
------------------------------------------------------------
#include "stdafx.h"
#include <conio.h>
int a[2][3]=
{
    11,12,13,
    21,22,23
};
int main(int argc, char *argv[])
{
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<3;j++)
        {
            printf("a[%d][%d] is %d\n",i,j,a[i][j]);
        }
        printf("\n");
    }
    _getch();
    return 0;
}

------------------------------------------------------------
动态创建2维数组 -- 两种方法:
------------------------------------------------------------
方法1.先申请全部行首指针,再按行逐行申请,常规方法,用法简单,我通常还是用此法。
------------------------------------------------------------
#include "stdafx.h"
#include <conio.h>

int main(int argc, char *argv[])
{
    int **a = new int *[2];
    for(int i=0; i<2; i++)
    {
        a[i]=new int *[3];
    }
// 先申请完内存,然后再赋值
    _getch();
    return 0;
}
注意, 这样分配的内存,有多块内存, a[i][j] 是指向多个内存块的。

注意2, int 和 int * 大小是不一定相等的,例如在64bits机器上,前者为4,后者为8.

           曾经有一个程序按int 保存指针大小,在32bits 上没发现问题,在64bits上总是崩溃,就是这个原因造成.修改后解决问题.
------------------------------------------------------------
方法2.转化为一维数组申请,
实际上也是方法1,只是巧妙安排了行首指针,使指针与数据连接在一起。

并且让指针所指的位置,正好与静态数组的计算方法相同.
这样,a[i][j] 数据可以集中到一个内存块中,就是所说的连续的内存空间了。 释放内存也方便了,只释放一次便可。
------------------------------------------------------------
用法:(像静态数组一样使用动态数组,只申请一次内存,创建过程稍微复杂一点)
struct xxx **data = (struct xxx **) arr_new(2, 3, sizeof(struct xxx));
这里就可以用 data[1][2]  ... data[0][1] ... 来操作了:)
arr_free(data);

完整示例:

#include "stdafx.h"
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void **darray_new(int row, int col, int size);
int main(int argc, char *argv[])
{
    int **a = (int **)darray_new(2,3,4);
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<3; j++)
        {
            a[i][j]=i*j;
        }
    }

    _getch();
    return 0;
}

void **darray_new(int row, int col, int size)

{       
        void **arr;

        arr = (void **) malloc(sizeof(void *) * row + size * row * col);
        if (arr != NULL)
        {
                char *head;

                head = (char *) arr + sizeof(void *) * row;
                memset(arr, 0, sizeof(void *) * row + size * row * col);
                while (row--)   // row 为1时,向0行填充,为0时退出,刚好满足要求           
                        arr[row] = head + size * row * col;               
        }
        return arr;
}

void darray_free(void **arr)
{
        if (arr != NULL)
                free(arr);       
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值