变长数组解析(原)
(一)变长一维数组
这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做:
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;
}
以下是运行结果:
以上可以显示分配的内存空间单元的地址,大家可以看到,由于数组空间是动态分配的,数组行之间的地址空间是不连续的,因为不同行的数组元素的地址空间是用不同的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)));其实这些东西用熟练了就可以了。也参考了一些资料,就不列,对不起了,被我参考的资料的作者们。抱歉啊!!