• C申请动态数组好文-转


    C/C++中动态申请二维数组的方式,测试代码如下:

    #include <cstdio>

    /*二级指针**作为形参,可以接受二级指针**p、指针数组*p[]作为实参的参数,从而传递二维数组*/
    void print(int **p, int row, int col)
    {
     int i=0,j=0;
     for(i=0;i<row;i++)
     {
      for(j=0;j<col;j++)
      {
       printf("%d ",p[i][j]);
      }
     }
     printf(" ");
    }
    /*数组指针(*)[]作为形参,可以接受数组指针(*p)[3]作为实参的参数,从而传递二维数组*/
    void print(int (*p)[3], int row, int col)
    {
     int i=0,j=0;
     for(i=0;i<row;i++)
     {
      for(j=0;j<3;j++)
      {
       printf("%d ",p[i][j]);
      }
     }
     printf(" ");
    }

    /************************************************************************/
    /*  以下是动态申请二维数组的几种方法     

    int ** Ptr <==> int Ptr[ x ][ y ]; 行列不固定
    int *Ptr[ 5 ] <==> int Ptr[ 5 ][ x ]; 行数固定
    int ( *Ptr )[ 5 ] <==> int Ptr[ x ][ 5 ]; 列数固定
    这里 x 和 y 是表示若干的意思。                            */
    /************************************************************************/

    /*方法一:二级指针,需要两次初始化,并且申请出来的二维数组只是逻辑上连续,物理上并不连续*/
    void init1()
    {
     int **p;
     int i=0,j=0;
     int row=4,col=3;
     p = new int*[row];//先初始化二级指针
     for(i=0;i<row;i++)//再初始化二级指针所指的指针数组的每个指针元素
     {
      //*(p+i) = new int[col];
      p[i] = new int[col];
     }
     
     //赋值
     for (i=0;i<row;i++)
     {
      for (j=0;j<col;j++)
      {
       p[i][j]=7;
      }
     }
     print(p,row,col);

     //释放空间要注意顺序
     for (i=0;i<row;i++)
     {
      //delete[] *(p+i);
      delete[] p[i];
      printf("init1 释放p[%d] ",i);
     }
     delete[] p;
     printf(" init1 二级指针**p被释放 ");
    }
    /*方法二:数组指针,这里可以一次性申请一片连续空间的二维数组*/
    void init2()
    {
     int i=0,j=0,row=4;
     const int col = 3;
     //int (*p)[col] = new int[row][col];//一步直接申请到位
     int (*p)[col] = (int(*)[col])new int[row*col];
     //赋值
     for (i=0;i<row;i++)
     {
      for (j=0;j<col;j++)
      {
       p[i][j]=8;
      }
     }
     print(p,row,col);
     delete[] p;
     printf("init2 数组指针(*p)[]被释放 ");
    }
    /*方法三:也是二级指针,语法上难理解一些,因为在直接操作地址,但是这个事一次性把二维数组所需空间申请完,而不是像方法一一样要多次申请。因此效率更高*/
    void init3()
    {
     int **p;
     int i=0;
     int row=4,col=3;
     p = (int **)new int[row+row*col];//这个空间包含了4个指针和12个数组元素(注意这里有一个bug,因为在32位系统所以指针位数和int位数一样长,如果在64位系统可能会出错)
     int *head = (int *)((int)p+row*sizeof(int *));//计算出二维数组的首地址
     for (i=0;i<row;i++)
     {
      p[i] = (int *)((int)head+i*col*sizeof(int));//给4个指针赋二维数组每一行的地址值
     }

     for (i=0;i<row;i++)
     {
      for (int j=0;j<col;j++)
      {
       p[i][j] = 9;
      }
     }
     print(p,row,col);
     delete[] p;
     printf("init3 高效版二级指针**p被释放 ");
     
    }
    /*方法四:指针数组,行数是固定的*/
    void init4()
    {
     const int row=4;
        int col=3;
     int *p[row];
     int i=0,j=0;

     for(i=0;i<row;i++)//再初始化指针所指的数组行地址
     {
      //*(p+i) = new int[col];
      p[i] = new int[col];
     }
     
     //赋值
     for (i=0;i<row;i++)
     {
      for (j=0;j<col;j++)
      {
       p[i][j]=6;
      }
     }
     print(p,row,col);

     delete[] *p;//!!!注意指针数组的释放方式
     printf("init4 指针数组*p[]被释放 ");
    }


    int main()
    {
     init1();
     init2();
     init3();
     init4();
     return 0;
    }

    ------------------------------分割线------------------------------

    C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm

    读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

    读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm

    读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm

    将C语言梳理一下,分布在以下10个章节中:

    1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
    2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
    3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
    4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
    5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
    6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
    7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
    8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
    9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
    10. Linux-C成长之路(十):其他高级议题

    本文永久更新链接地址http://www.linuxidc.com/Linux/2015-03/115054.htm 

  • 相关阅读:
    .net core 2.x默认不支持gb2312
    获取枚举描述
    C#中DateTime.Ticks
    验证组件FluentValidation的使用示例
    python计算出现错误
    EF的导航属性
    webpack不打包指定的js文件
    递归树处理,配合vue的vueTreeselect组件使用
    elementUI 日期时间选择器el-date-picker开始时间与结束时间约束
    Vue2+Webpack+ES6 兼容低版本浏览器(IE9)解决方案
  • 原文地址:https://www.cnblogs.com/Erdos001/p/5610811.html
Copyright © 2020-2023  润新知