变长数组解析(原)

(一)变长一维数组

    这里说的灯泡变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做:

   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];
    当然使用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:    }  

(二)变长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];
    其中,num1是行数,num2是数组的列数。测试的源程序如下:

#include <iostream>
#include <iomanip>
using namespace std;  
 
int main(int argc, char **argv)  
{  
    int num1;
    int num2;
 
    cout << "请输入行列的值:"<< endl;
    cin >> num1 >> num2;
 
    int **p = new int *[num1];
 
    for (int j = 0; j < num1; ++j)
    {
        p[j] = new int[num2];
        for (int k = 0; k < num2; ++k)
        {
            p[j][k] = (j + 1)*(k + 1);
            cout << setw(6) << p[j][k] << ":" << setw(8) << &p[j][k];
        }
        cout << endl;
    }
 
    for (int i = 0; i < num1; ++i)
    {
        delete[] p[i];
    }
        
    delete[] p;
    return 0;  
}  

以下是运行结果:

CEUCIZZLKR44NMLVIG0B4_thumb

    以上可以显示分配的内存空间单元的地址,大家可以看到,由于数组空间是动态分配的,数组行之间的地址空间是不连续的,因为不同行的数组元素的地址空间是用不同的new来分配的。而每一行之中列之间的地址空间是连续的。
那么用vector(向量)怎样实现二维数组呢?以下给出源程序:

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;  
 
int main(int argc, char **argv)  
{  
    int num1;
    int num2;
 
    cout << "请输入行列的值:"<< endl;
    cin >> num1 >> num2;
 
    vector<vector<int> > veciv(num1);
 
    for (int i = 0; i < num1; ++i)
    {
        for (int j = 0; j < num2; ++j)
        {
            veciv[i].push_back(i*j);
            cout << setw(6) << veciv[i][j] << ": "<< setw(8) << &veciv[i][j]; 
        }
        cout << endl;
    }
    
    return 0;  
}  

也可以用resize来做:

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;  
 
int main(int argc, char **argv)  
{  
    int num1;
    int num2;
 
    cout << "请输入行列的值:"<< endl;
    cin >> num1 >> num2;
 
    vector<vector<int> > veciv(num1);
 
    for (int i = 0; i < num1; ++i)
    {
        veciv[i].resize(num2);
        for (int j = 0; j < num2; ++j)
        {
            veciv[i][j] = (i + 1)*(j + 1);
            cout << setw(6) << veciv[i][j] << ": "<< setw(8) << &veciv[i][j]; 
        }
        cout << endl;
    }
 
    return 0;  
}  

    如果用三维数组,vector<vector<int> > > veciv(m, vector<vector<int> >(n, vector<int>(l)));其实这些东西用熟练了就可以了。也参考了一些资料,就不列,对不起了,被我参考的资料的作者们。抱歉啊!!大笑

posted @ 2012-02-07 22:33  云端小飞象cg  阅读(2491)  评论(0编辑  收藏  举报