歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C/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\t",p[i][j]);
  }
 }
 printf("\n");
}
/*數組指針(*)[]作為形參,可以接受數組指針(*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\t",p[i][j]);
  }
 }
 printf("\n");
}

/************************************************************************/
/*  以下是動態申請二維數組的幾種方法     

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]\t",i);
 }
 delete[] p;
 printf("\ninit1 二級指針**p被釋放\n");
}
/*方法二:數組指針,這裡可以一次性申請一片連續空間的二維數組*/
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)[]被釋放\n");
}
/*方法三:也是二級指針,語法上難理解一些,因為在直接操作地址,但是這個事一次性把二維數組所需空間申請完,而不是像方法一一樣要多次申請。因此效率更高*/
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被釋放\n");
 
}
/*方法四:指針數組,行數是固定的*/
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[]被釋放\n");
}


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成長之路(十):其他高級議題

Copyright © Linux教程網 All Rights Reserved