天天看點

C++動态數組 本文摘自:http://www.cnblogs.com/lxshanye/archive/2013/05/20/3088558.html#top C++動态數組

本文摘自:http://www.cnblogs.com/lxshanye/archive/2013/05/20/3088558.html#top

C++動态數組

1.變長一維數組   

  這裡說的變長數組是指在編譯時不能确定數組長度,程式在運作時需要動态配置設定記憶體空間的數組。實作變長數組最簡單的是變長一維數組,你可以這樣做: 

   1:    //檔案名:   array01.cpp 

   2:    #include<iostream> 

   3:    using   namespace   std; 

   4:    int   main() 

   5:    { 

   6:      int   len; 

   7:      cin>>len; 

   8:      //用指針p指向new動态配置設定的長度為len*sizeof(int)的記憶體空間 

   9:      int   *p=new   int[len]; 

  10:      ........... 

  11:      delete[]   p; 

  12:      return   0; 

  13:    } 

  注意int   *p=new   int[len];這一句,你不能這樣做:   

  int   p[len];   

  C++編譯器會報錯說len的大小不能确定,因為用這種形式聲明數組,數組的大小需要在編譯時确定。而且這樣也不行:   

  int   p[]=new   int[len];   

  編譯器會說不能把int*型轉化為int[]型,因為用new開辟了一段記憶體空間後會傳回這段記憶體的首位址,是以要把這個位址賦給一個指針,是以要用int   *p=new   int[len];   

  array01.cpp實作了一個變長的一維數組,但是要養成一個好習慣,就是注意要登出指針p,使程式釋放用new開辟的記憶體空間。   

  當然使用C++标準模版庫(STL)中的vector(向量)也可以實作變長數組: 

   1:    //檔案名:   array02.cpp 

   2:    #include<iostream> 

   3:    #include<vector> 

   4:    using   namespace   std; 

   5:    int   main() 

   6:    { 

   7:      int   len; 

   8:      cin>>len; 

   9:      vector<int>   array(len);//聲明變長數組 

  10:      for(int   i=0;i<len;i++) 

  11:      { 

  12:        array[i]=i; 

  13:        cout<<array[i]<<"/t"; 

  14:      } 

  15:      return   0; 

  16:    } 

  這裡的變長數組讓我聯想到了java的java.util包中的vector和C#中的ArrayList,它們也可以在各自的語言中實作變長數組。不過C++中的vector不能像C#一樣有托管的垃圾回收機制回收被占用的記憶體空間,但是你可以在使用完vector後調用~vector()析構函數釋放記憶體。   

  2.變長n維數組   

  變長的n維數組實作起來有些麻煩,但是在工程與軟體設計應用中常使用的是二維數組,是以在這裡着重介紹變長的二維數組,變長的n維數組可以按照類似的方法實作。首先看一個經典的用C實作變長二維數組的例子:  

   1:    //檔案名:   array03.c 

   2:    #include     <stdio.h>     

   3:    #include     <malloc.h>     

   4:    void     main()     

   5:    {     

   6:                          int     x,y,i,j;     

   7:                          float     **a,*b;     

   8:                                                  printf("請輸入你所求解的線性方程組的行數x:x=");     

   9:                          scanf("%d",&x);     

  10:                                                  printf("請輸入你所求解的線性方程組的列數y:y=");     

  11:                          scanf("%d",&y);     

  12:                  a=(float     **)malloc(sizeof(float     *)     *x);     

  13:                  b=(float     *)malloc(sizeof(float)     *x);     

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

  15:                          {     

  16:                                                  *(a+i)=(float     *)malloc(sizeof(float)     *y);      

  17:                          }     

  18:         

  19:                          printf("請按行的順序依次輸入系數的值(共%d項):",x*y);     

  20:                          for(i=0;i<=x-1;i++)     

  21:                                                  for(j=0;j<=y-1;j++)     

  22:                                                                          scanf("%f",&a[i][j]);     

  23:                          printf("請按列的順序依次輸入常數的值(共%d項):",x);     

  24:                          for(j=0;j<=x-1;j++)     

  25:                                                                          scanf("%f",&b[j]);     

  26:                          printf("您輸入方程組的增廣矩陣為:/n");     

  27:                          for(i=0;i<=x-1;i++)     

  28:                          {     

  29:                                                  for(j=0;j<=y-1;j++)     

  30:                                                                          printf("%.5f         ",a[i][j]);     

  31:                                                  printf("%.5f         ",b[i]);     

  32:                                                  printf("/n");     

  33:                          }     

  34:                          free(b);     

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

  36:                                                  free     (*(a+i));   

  37:    } 

  那麼用C++怎樣實作呢?在C++中可以通過new和delete運算符動态開辟和釋放空間,其中new與C中malloc函數的功能相似,delete與C中free函數的功能相似。用C++實作變長二維數組時可以采用兩種方法:雙指針方法和使用STL中vector(向量)的方法。   

  首先介紹一下雙指針方法,在這裡雙指針就是指像指針的指針,比如你可以這樣聲明一個數組:   

  int   **p   =   new   int*[num1];   

  而對每一個*p(一共num1個*p)申請一組記憶體空間:   

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

    p[i]   =   new   int[num2];   

  其中,num1是行數,num2是數組的列數。測試的源程式如下:   

   1:   //檔案名:   array04.cpp 

   2:    #include   <iostream> 

   3:    #include   <iomanip> 

   4:    using   namespace   std; 

   5:    int   main() 

   6:    { 

   7:      int   num1,//行數 

   8:              num2;//列數 

   9:      cout<<"Please   enter   the   number   for   row   and   column:   "<<endl; 

  10:      cin   >>   num1   >>   num2; 

  11:      //為二維數組開辟空間 

  12:      int   **p   =   new   int*[num1]; 

  13:      for(int   i=0;   i<num1;   ++i) 

  14:        p[i]   =   new   int[num2]; 

  15:      for(int   j=0;j<num1;j++) 

  16:      { 

  17:        for(int   k=0;k<num2;k++) 

  18:        { 

  19:          p[j][k]=(j+1)*(k+1); 

  20:          cout<<setw(6)<<p[j][k]<<':'<<setw(8)<<&p[j][k]; 

  21:        } 

  22:        cout<<endl; 

  23:      } 

  24:      //釋放二維數組占用的空間 

  25:      for(int   m=0;m<num1;m++) 

  26:        delete[]   p[m]; 

  27:      delete[]   p; 

  28:      return   0; 

  29:    } 

  以下是運作結果:   

  Please   enter   the   number   for   row   and   column:   

  4   5   

            1:004915F0           2:004915F4           3:004915F8           4:004915FC           5:00491600   

            2:00491180           4:00491184           6:00491188           8:0049118C         10:00491190   

            3:00491140           6:00491144           9:00491148         12:0049114C         15:00491150   

            4:00491100           8:00491104         12:00491108         16:0049110C         20:00491110   

  Press   any   key   to   continue   

  程式清單array04.cpp可以顯示配置設定的記憶體空間單元的位址,大家可以看到,由于數組空間是動态配置設定的,數組行之間的位址空間是不連續的,因為不同行的數組元素的位址空間是用不同的new來配置設定的。而每一行之中列之間的位址空間是連續的。   

  那麼用vector(向量)怎樣實作二維數組呢?以下給出源程式:   

   1:   //檔案名:   array05.cpp 

   2:    #include   <iostream> 

   3:    #include   <vector> 

   4:    #include   <iomanip> 

   5:    using   namespace   std; 

   6:    int   main() 

   7:    { 

   8:      int   i, 

   9:              j, 

  10:              m,   //行數 

  11:              n;   //列數 

  12:      cout   <<   "input   value   for   m,n:"; 

  13:      cin>>m>>n; 

  14:      //注意下面這一行:vector<int後兩個">"之間要有空格!否則會被認為是重載">>"。 

  15:      vector<vector<int>   >   vecInt(m,   vector<int>(n));     

  16:      for   (i   =   0;   i   <   m;   i++) 

  17:        for   (j   =   0;   j   <   n;   j++) 

  18:          vecInt[i][j]   =   i*j;   

  19:      for   (i   =   0;   i   <   m;   i++) 

  20:      { 

  21:        for   (j   =   0;   j   <   n;   j++) 

  22:          cout<<setw(5)<<vecInt[i][j]<<":"<<setw(9)<<&vecInt[i][j]; 

  23:        cout<<endl; 

  24:      }     

  25:      return   0; 

  26:    } 

  以下是運作結果:   

  input   value   for   m,n:3   4   

          0:   00491180         0:   00491184         0:   00491188         0:   0049118C   

          0:   00491140         1:   00491144         2:   00491148         3:   0049114C   

          0:   00491100         2:   00491104         4:   00491108         6:   0049110C   

  Press   any   key   to   continue   

  大家可以看到,這裡vector中元素的記憶體的位址配置設定也有同雙指針實作的二維數組有同樣的特點。不過用vector的方法比使用雙指針簡單地多,配置設定記憶體空間時會更安全,數組初始化代碼也更簡單,是以本人建議使用STL中的vector來實作變長多元數組。以下是一個變長三維數組:)  

   1:    //檔案名:   array06.cpp 

   2:    #include   <iostream> 

   3:    #include   <vector> 

   4:    #include   <iomanip> 

   5:    using   namespace   std; 

   6:    int   main() 

   7:    { 

   8:      int   i, 

   9:        j, 

  10:        k, 

  11:        m,   //一維坐标 

  12:        n,   //二維坐标 

  13:        l;   //三維坐标         

  14:      cout   <<   "input   value   for   m,n,l:"; 

  15:      cin>>m>>n>>l; 

  16:      vector<vector<vector<int>   >   >   vecInt(m,   vector<vector<int>   >(n,   vector<int>(l)));     

  17:      for   (i   =   0;   i   <   m;   i++) 

  18:        for   (j   =   0;   j   <   n;   j++) 

  19:          for(k   =   0;   k   <   l;   k++) 

  20:            vecInt[i][j][k]   =   i+j+k;   

  21:      for   (i   =   0;   i   <   m;   i++) 

  22:      { 

  23:        for   (j   =   0;   j   <   n;   j++) 

  24:        { 

  25:          for(k   =   0;   k<l;   k++) 

  26:            cout<<setw(5)<<vecInt[i][j][k]<<":"<<setw(9)<<&vecInt[i][j][k]; 

  27:          cout<<endl; 

  28:        } 

  29:        cout<<endl; 

  30:      } 

  31:      return   0; 

  32:    } 

  運作結果:   

  input   value   for   m,n,l:2   3   4   

          0:   00492FE0         1:   00492FE4         2:   00492FE8         3:   00492FEC   

          1:   00492FA0         2:   00492FA4         3:   00492FA8         4:   00492FAC   

          2:   00492F60         3:   00492F64         4:   00492F68         5:   00492F6C   

          1:   00492EC0         2:   00492EC4         3:   00492EC8         4:   00492ECC   

          2:   00492E80         3:   00492E84         4:   00492E88         5:   00492E8C   

          3:   00492E40         4:   00492E44         5:   00492E48         6:   00492E4C