1: 二维数组的初始化
(1) C风格,数组的自动分配方式。这种方式内存在栈上申请,不用手动销毁内存。注意:数组维度不能太大,否则会爆栈溢出;同时数组元素访问\赋值注意数组越界问题。
const int row = 2;
const int col = 3;
int arr[row][col]; // 编译器识别的类型是 int(*)[3]
(2) C风格,malloc手动分配方式。这种方式内存在堆上申请,用完需要free手动销毁内存。如果不销毁,会造成内存泄漏。
const int row = 2;
const int col = 3;
int** array = (int**)malloc(sizeof(int*) * row);
for (int i = 0; i < row; i++) {
array[i] = (int*)malloc(sizeof(int) * col);
}
释放:
for (int i = 0; i < row; i++) {
free(array[i]);
}
free(array);
(3) C++风格, new手动分配。同样也是在堆上申请内存空间,需要用delete []来手动释放。
const int row = 2;
const int col = 3;
int** array = new int* [row];
for (int i = 0; i < row; i++) {
array[i] = new int [col];
}
释放
for (int i = 0; i < row; i++) {
delete [] array[i]
}
deletet [] array;
2: 二维数组作为参数 (原则上形参和实参类型要保持一致)
(1) 形参为数组
这种场景形参为 int array[][col], 这种参数要指定第二维列的长度。同时要入参中指定行、列。
由于二维数组在内存中是行存储的,需要给定一个列值,编译器才能去寻址,内部寻址是array+i*col+j; 常用使用p[i][j]访问元素。要求实参定义是自动的数组分配方式。
void func(int array[][5], int row, int col)
{
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++)
cout << p[i][j]<<endl;
}
}
(2) 形参为双指针
这种场景形参为 int** array。要求实参定义是手动分配方式。
void func(int** array, int row, int col)
{
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++)
cout << p[i][j]<<endl;
}
}
(3) 形参是数组+指针形式
这种场景形参为int (*array)[col]。 要求实参定义是自动的数组分配方式。
这个是int array[][col]的变种类型。
void func(int (*array)[5], int row, int col)
{
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++)
cout << p[i][j]<<endl;
}
}
(4) 形参是单指针 (少用)
实参也是单指针类型, eg: int* array = new int[row * col]; 用一维指针当二维数组用。
void func(int *array, int row, int col)
{
for(int i = 0; i < row; i++) {
for (int j = 0; j < col; j++)
cout << *(array + i * col + j) <<endl;
}
}