【22】C语言 - 二维数组详解
【22】C语言 - 二维数组详解
文章目录
- 1. 二维数组介绍
- 2. 二维数组的声明
- 3. 二维数组的初始化
- 方法一:先声明,再初始化
- 方法二:声明的同时,并初始化
- 方法三:直接列出所有元素(编译器自动计算行数)
- 方法四:部分初始化
- 4. 访问二维数组的元素
- 5. 使用循环遍历二维数组
- 6. 内存中的存储方式
- 7. 将二维数组传递给函数
- 8. 总结与要点
1. 二维数组介绍
一个二维数组可以被直观地理解为一个由行和列组成的表格。
例如,一个2行3列的二维数组可以这样表示:
| 行/列 | 列0 | 列1 | 列2 |
|---|---|---|---|
| 行0 | [0][0] | [0][1] | [0][2] |
| 行1 | [1][0] | [1][1] | [1][2] |
每个元素通过两个索引(下标)来访问:第一个索引代表行号,第二个索引代表列号。索引总是从0开始。
2. 二维数组的声明
声明一个二维数组需要指定行数和列数。
语法:
数据类型 数组名[行数][列数];
示例:
int matrix[3][4]; // 声明一个3行4列(共12个元素)的整型二维数组
float temperatures[5][7]; // 声明一个5行7列的浮点型二维数组
char chessBoard[8][8]; // 声明一个8行8列的字符型二维数组(如棋盘)
3. 二维数组的初始化
方法一:先声明,再初始化
#include <stdio.h>int main(){//1.先声明再初始化int arr[3][2];arr1[0][0] = 1;arr1[0][1] = 2;arr1[1][0] = 3;arr1[1][1] = 4;arr1[2][0] = 5;arr1[2][1] = 6;return 0;
}
方法二:声明的同时,并初始化
#include <stdio.h>int main(){int matrix[2][3] = {{1, 2, 3}, // 第0行的元素{4, 5, 6} // 第1行的元素};return 0;
}
方法三:直接列出所有元素(编译器自动计算行数)
一层大括号自动分配。
#include <stdio.h>int main(){int arr[2][4] = {1,2,3,4,5,6,7,8};return 0;
}
可以省略行数,编译器会根据你提供的数据自动计算行数。但列数绝对不能省略。
#include <stdio.h>int main(){int arr4[][3] = {1,2,3,4,5,6};return 0;
}
方法四:部分初始化
未显式初始化的元素会被自动设置为0。
#include <stdio.h>int main(){
// 只初始化第一行,其余行自动为0
int arr1[3][4] = {{1}, {2, 3}};
/* 结果为:行0: 1, 0, 0, 0行1: 2, 3, 0, 0行2: 0, 0, 0, 0
*/// 将所有元素初始化为0的最简单方法
int arr2[3][4] = {0};
}
4. 访问二维数组的元素
使用数组名后跟两个方括号 [行索引][列索引] 来访问或修改元素。
示例:
#include <stdio.h>int main() {int table[2][3] = {{10, 20, 30},{40, 50, 60}};// 访问单个元素printf("table[0][1] = %d\n", table[0][1]); // 输出:20printf("table[1][2] = %d\n", table[1][2]); // 输出:60// 修改元素table[1][0] = 99;printf("修改后 table[1][0] = %d\n", table[1][0]); // 输出:99return 0;
}
5. 使用循环遍历二维数组
遍历二维数组通常需要使用两层嵌套的循环。
外层循环控制行,内层循环控制列。
示例:打印整个数组
#include <stdio.h>int main() {int rows = 2, cols = 3;int table[2][3] = {{1, 2, 3}, {4, 5, 6}};// 遍历打印for (int i = 0; i < rows; i++) { // i 循环行for (int j = 0; j < cols; j++) { // j 循环列printf("%d ", table[i][j]);}printf("\n"); // 打印完一行后换行}/* 输出:1 2 34 5 6*/return 0;
}
6. 内存中的存储方式
这是理解二维数组的关键:二维数组在内存中是按行优先的顺序连续存储的。
对于数组 int arr[2][3] = {{1,2,3}, {4,5,6}};,它在内存中的排列顺序是:
行0: 1, 2, 3,
行1: 4, 5, 6
物理地址是连续的:1的地址后面紧跟着2,然后是3,再然后是4,以此类推。
正因为这种连续的线性存储,我们可以用单层循环和指针来遍历它,但更常见的还是用双层循环。
7. 将二维数组传递给函数
将二维数组作为参数传递给函数时,必须指定列的大小。
这是因为编译器需要知道一行有多少个元素,才能正确计算内存地址。
函数原型示例:
// 正确:指定了列数
void printMatrix(int arr[][4], int rows) {// ...
}// 也可以明确写出行列,但行数会被忽略,通常用变量传递
void printMatrix(int arr[][4], int rows) {// ...
}// 错误:没有指定列数
// void printMatrix(int arr[][], int rows, int cols);
完整示例:
#include <stdio.h>// 函数定义,必须指定列数(这里是4)
void printArray(int arr[][4], int rows) {for (int i = 0; i < rows; i++) {for (int j = 0; j < 4; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}int main() {int myArray[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};printArray(myArray, 3); // 将数组传递给函数return 0;
}
8. 总结与要点
| 特性 | 说明 |
|---|---|
| 本质 | 一个“数组的数组”,是逻辑上的表格,物理上的连续内存块。 |
| 声明 | type name[rows][cols]; |
| 初始化 | 推荐按行用{}初始化。可以省略行数,但不能省略列数。 |
| 访问 | array[i][j],i为行索引,j为列索引,都从0开始。 |
| 遍历 | 使用两层嵌套循环,外层循环行,内层循环列。 |
| 内存 | 按“行优先”顺序连续存储。 |
| 传参 | 函数参数中必须指定列数(如int arr[][4])。 |
