现在的位置: 首页 > 综合 > 正文

c++二维数组的使用

2012年05月25日 ⁄ 综合 ⁄ 共 5220字 ⁄ 字号 评论关闭

  1.A为类型         
    A (*ga)[n] = new A[m][n];    
        ...      
      delete ga[];  
  缺点:n必须是已知优点:  
  调用直观,连续储存,程序简洁(经过测试,析构函数能正确调用)  
   
  2.    
    A **ga = new A *[m];        
    for(int i = 0; i < m; i++)          
          ga[i] = new A[n];        
    ...      
      for(int   i   =   0;   i   <   m;   i++)                
    delete   []ga[i];          
  delete   []ga;  
  缺点:非连续储存,程序烦琐,  
  ga为A**类型优点:调用直观,  
  n可以不是已知  
   
  3.      
  A * ga  =  new A[m*n];        
    ...        
    delete []ga;  
  缺点:调用不够直观优点:  
  连续储存,n可以不是已知  
   
  4.      
  vector<vector<A>   >   ga;          
  ga.resize(m);                                               //这三行可用可不用        
    for(int   i   =   1;   i   <   n;   i++)                     //              
      ga[i].resize(n);                                 //        

     ...

  缺点:非连续储存,调试不够方便,编译速度下降,程序膨胀(实际速度差别不大)  
  优点:调用直观,自动析构与释放内存,可以调用stl相关函数,动态增长  
   
  5.     vector<A>   ga;        
    ga.resize(m*n);  
  方法3,4的结合  
   
  6.   2的改进版(Penrose提供,在此感谢)    
        A ** ga  =  new A*[m];        
    ga[0]  =  new A[m*n];      
      for(int i = 1; i < m; i++)          
          ga[i] = ga[i-1]+n;      
      ...        
    delete   []   ga[0];      
      delete   []   ga;  
  缺点:程序烦琐,ga为A**类型优点:连续储存,调用直观,n可以不是已知

附:1,2,3,6还有对应的malloc-free版本个人推荐1和4,2可以用4来代替,3,5调用太烦琐,毕竟源程序是拿来看的不是拿来运行的

 

下面是一些错误和没成功的版本

1.   A* ga = new A[m][n];     必然错误

2.   vector<A[n]> ga;       ga.resize(m);        
  gcc   3.2下编译失败,不知道其它编译器效果如何也不知道标准是否允许

 

动态二维数组生成:

传统的解决方案是分配一个指针数组, 然后把每个指针初始化为动态分配的 ``列"。 以下为一个二维的例子:

//typedef int (*arraypoiter)[ncolumns];

int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)

{   

        unsigned int i;

        int **array = (int **)malloc(nrows * sizeof(int *));

        for(i = 0; i < nrows; i++)

                array[i] = (int *)malloc(ncolumns * sizeof(int));

 

        printf("array=0x%x/n",(int)array);

        for(i=0;i<nrows;i++)

        {

                printf("array[%d]=0x%x/n",i,(int)array[i]);

        }

        printf("/n");

    return array;

}
 

void main(void)

{

        int **test_allocate;

        unsigned int nrows=3;

        unsigned int ncolumns=4;

 

        test_allocate = dynamic_alloc_arrays(nrows,ncolumns);

        printf("test_allocate=%x/n",test_allocate);

}

 

当然, 在真实代码中, 所有的 malloc 返回值都必须检查。你也可以使用 sizeof(*array)  和 sizeof(**array) 代替 sizeof(int *) 和 sizeof(int)(因为*array的类型为int *,**array的类型为int)。

 你可以让数组的内存连续, 但在后来重新分配列的时候会比较困难, 得使用一点指针算术: 

int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)

{   

        unsigned int i; 

        int **array = (int **)malloc(nrows * sizeof(int *));

        array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));

        for(i = 1; i < nrows; i++)

               array[i] = array[0] + i * ncolumns;  

        printf("array=0x%x/n",(int)array); 

        for(i=0;i<nrows;i++) 

        { 

                printf("array[%d]=0x%x/n",i,(int)array[i]); 

        } 

        printf("/n"); 

    return array; 

void main(void) 

        int **test_allocate; 

        unsigned int nrows=3;

        unsigned int ncolumns=4; 

        test_allocate = dynamic_alloc_arrays(nrows,ncolumns);

        printf("test_allocate=%x/n",test_allocate); 

}

 

在两种情况下, 动态数组的成员都可以用正常的数组下标 arrayx[i][j] 来访问  (for 0 <= i <nrows 和 0 <= j <ncolumns)。

另一种选择是使用数组指针:

    int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));

但是这个语法变得可怕而且运行时最多只能确定一维。因为NCOLUMNS必须为定值

 

××××××××××××××××××××××××××××××××××××××

C语言里,数组名是被看作指针来使用的,一维数组是指针,二维数组是指向指针的指针,三维是......... 真的是这样的吗??看下面的例子:

void    show (int * * info, int x, int y) //打印一个x*y的数组的内容

{

        int   i, j;

        for (i=0;i<x;i++)

        {

                for (j=0;j<y;j++)

                {

                       printf ("%d  ",info[i][j]);

                }

                printf ("/n");

        }

}

void    Function (void)

{               

       int  as[10][10];

        show (as,10,10);

// error C2664: 'show' : cannot convert parameter 1 from 'int [10][10]' to 'int ** ' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

}

在C中没有安全类型检查,上述程序只是warning,但是程序运行会崩溃

在C++中,根本就无法编译通过,即as[10][10]和int * *根本不是一个类型

 

为什么?在c中,二维数组虽然是定义为指向指针的指针,但是实际上被指向的指针是不存在的,即没有一个内存来存储这个指针,只是在执行as [n]时返回一个指针罢了,as所指的不过是存放数组内容的地址!!

 

实际上从上面**P和动态二维数组的使用即可看出来,**P和静态二维数组的本质区别!

 另外一个实现动态二维数组方法

 

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

int *ywshuzumalloc(int n)   //一维数组分配
{
    int *a;
    a=(int *)malloc(sizeof(int)*n);
    return a;
}

int **ewshuzumalloc(int m,int n)   //二维数组分配
{
    int **a;
    int i;
    a=(int **)malloc(m*sizeof(int *));
    for (i=0;i<m;i++)
        a[i]=(int *)malloc(n*sizeof(int));
    return a;
}

int ***swshuzumalloc(int m,int n,int o) //三维数组分配
{
    int ***a;
    int i,j;
    a=(int ***)malloc(m*sizeof(int **));
    for(i=0;i<m;i++)
        a[i]=(int **)malloc(n*sizeof(int *));
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
            a[i][j]=(int *)malloc(o*sizeof(int));
    }
    return a;
}

void main()
{
    int *a;
    int **b;
    int ***c;
    int i,j,k,m,n,o;
    int lenght;
    printf("请输入动态分配一维数组的个数:/n");
    scanf("%d",&n);
    a=ywshuzumalloc(n);
    for(i=0;i<n;i++)
    {
        a[i]=i+1;
        printf("%d ",a[i]);
    }
    printf("/n");

    lenght=n;
    printf("该数组的长度是: %d",lenght);
    printf("/n");

    printf("请输入动态分配二维数组的个数:/n");
    scanf("%d %d",&m,&n);
    b=ewshuzumalloc(m,n);
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            b[i][j]=(i+1)*10+j+1;
            printf("%d ",b[i][j]);
        }
        printf("/n");
    }
    printf("/n");
    lenght=m*n;
    printf("该数组的长度是: %d",lenght);
    printf("/n");
   
    printf("请输入动态分配三维数组的个数:/n");
    scanf("%d %d %d",&m,&n,&o);
    c=swshuzumalloc(m,n,o);
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<o;k++)
            {
                c[i][j][k]=(i+1)*100+(j+1)*10+k+1;
                printf("%d ",c[i][j][k]);
            }
            printf("/n");
        }
        printf("/n");
    }
    printf("/n");
    lenght=m*n*o;
    printf("该数组的长度是: %d",lenght);
    printf("/n");

}

 

抱歉!评论已关闭.