多维数组以指向 0 号元素的指针方式传递。多维数组的 元素本身就是数组。除了第一维以外的所有维的长度都是元素类型的一部分,必 须明确指定.---C++ Primer
这样理解比较好: 对于数组:
int a[5]; //a是包含5个int型的数组
int b[2][5]; //b是包含2个 int[5](包含5个int型的数字)的数组
对a来说,int 是类型, 对b来说 int[5]是类型
下面看下参数传递:
<!-- lang: cpp -->
#include <iostream>
using namespace std;
/**
* @param 1:a 是int[5]类型的指针
* @param 2:i 边界
*/
void print_values_one(int (*a)[5], int i)
{
for(int m = 0; m < i; ++ m)
{
for(int n = 0; n < 5; ++n)
{
cout << a[m][n] << " ";
}
cout << endl;
}
}
/**
* @param 1:a 元素是二维数组,每行是5个元素的一维数组
* @param 2:i 边界
*/
void print_values_two(int a[][5], int i)
{
for(int m = 0; m < i; ++ m)
{
for(int n = 0; n < 5; ++n)
{
cout << a[m][n] << " ";
}
cout << endl;
}
}
/**
* @param 1:a 是一个指向 int* 类型的指针
* @param 2:i 边界
* @param 3:j 边界
*/
void print_values_three(int ** a, int i, int j)
{
for(int m = 0; m < i; ++ m)
{
for(int n = 0; n < j; ++n)
{
cout << *( *(a + m) + n)<< " ";
}
cout << endl;
}
}
int main()
{
int a[2][5] = {
1, 2, 3, 4, 5,
6, 7, 7, 9, 10};
//下面是正确的
print_values_one(a, 2);//正确,因为print_values_one
print_values_two(a, 2);
//错误
//编译不通过,出现不能将int(*)[5]转化为int **,这是因为a的类型是固定的了,a可以看作一个指向int(*)[5]类型的首地址
//和int*类型不符,所以错误,跟上面说的类型相关.
//print_values_three(a, 2, 5);
int** b = new int* [2];
for(int i = 0; i < 2; ++ i)
{
*(b + i) = new int[5];
}
//这样就正确的,b和参数类型一致了.结果是随机值,没有进行赋值,这样写法仅供测试用
print_values_three(b, 2, 5);
for(int i = 0; i < 2; ++ i)
{
delete [] b[i];
}
delete [] b;
b = NULL;//置空
return 0;
}
动态分配的内存最后必须进行释放,否则,内存最终将会逐渐耗尽。如果不再需要使用动态创建的数组,程序员必须显式地将其占用的存储空间返还给程序的自由存储区。C++ 语言为指针提供 delete [] 表达式释放指针所指向的数组空间: delete [] pia; 该语句回收了 pia 所指向的数组,把相应的内存返还给自由存储区。在关键字 delete 和指针之间的空方括号对是必不可少的:它告诉编译器该指针指向的是自由存储区中的数组,而并非单个对象。 如果遗漏了空方括号对,这是一个编译器无法发现的错误,将导致程序在运行时出错。 理论上,回收数组时缺少空方括号对,至少会导致运行时少释放了内存空间,从而产生内存泄漏(memory leak)。