C 语言多维数组
外观
C语言多维数组[编辑 | 编辑源代码]
多维数组是C语言中存储表格状数据(如矩阵、三维空间坐标等)的核心数据结构。它本质上是"数组的数组",通过多个下标访问元素。本章将详细讲解二维、三维数组的声明、初始化、内存布局及实际应用。
基本概念[编辑 | 编辑源代码]
多维数组是线性数组在更高维度的扩展:
- 一维数组:单行数据(向量)
- 二维数组:行和列的表格(矩阵)
- 三维数组:多个表格的堆叠(如RGB图像数据)
数学上,二维数组可表示为:
声明与初始化[编辑 | 编辑源代码]
二维数组[编辑 | 编辑源代码]
// 声明3行2列的整型数组
int matrix[3][2];
// 声明时初始化(行数可省略)
int matrix[][2] = {{1, 2}, {3, 4}, {5, 6}};
三维数组[编辑 | 编辑源代码]
// 声明2个3x4的表格
int cube[2][3][4];
// 分层初始化
int cube[][3][4] = {
{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}, // 第一层
{{13,14,15,16}, {17,18,19,20}, {21,22,23,24}} // 第二层
};
内存布局[编辑 | 编辑源代码]
C语言采用行优先存储(Row-major order):
计算公式(二维数组):
访问元素[编辑 | 编辑源代码]
#include <stdio.h>
int main() {
float temperature[3][4] = {
{22.5, 23.1, 24.0, 23.7},
{21.8, 22.3, 23.5, 22.9},
{20.7, 21.2, 22.1, 21.5}
};
// 访问第2行第3列(0-based)
printf("周三中午温度: %.1f°C\n", temperature[2][3]);
// 遍历所有元素
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 4; j++) {
printf("%.1f\t", temperature[i][j]);
}
printf("\n");
}
return 0;
}
输出:
周三中午温度: 21.5°C 22.5 23.1 24.0 23.7 21.8 22.3 23.5 22.9 20.7 21.2 22.1 21.5
实际应用案例[编辑 | 编辑源代码]
案例1:矩阵乘法[编辑 | 编辑源代码]
#include <stdio.h>
#define ROWS_A 2
#define COLS_A 3
#define COLS_B 2
void matrix_multiply(int a[][COLS_A], int b[][COLS_B], int result[][COLS_B]) {
for(int i = 0; i < ROWS_A; i++) {
for(int j = 0; j < COLS_B; j++) {
result[i][j] = 0;
for(int k = 0; k < COLS_A; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
int main() {
int a[ROWS_A][COLS_A] = {{1, 2, 3}, {4, 5, 6}};
int b[COLS_A][COLS_B] = {{7, 8}, {9, 10}, {11, 12}};
int result[ROWS_A][COLS_B];
matrix_multiply(a, b, result);
// 输出结果矩阵
for(int i = 0; i < ROWS_A; i++) {
for(int j = 0; j < COLS_B; j++) {
printf("%d\t", result[i][j]);
}
printf("\n");
}
return 0;
}
输出:
58 64 139 154
案例2:三维坐标系统[编辑 | 编辑源代码]
#include <math.h>
typedef struct {
float points[100][3]; // 存储100个三维点
int count;
} PointCloud;
float calculate_distance(PointCloud pc, int index1, int index2) {
float dx = pc.points[index1][0] - pc.points[index2][0];
float dy = pc.points[index1][1] - pc.points[index2][1];
float dz = pc.points[index1][2] - pc.points[index2][2];
return sqrt(dx*dx + dy*dy + dz*dz);
}
高级主题[编辑 | 编辑源代码]
动态多维数组[编辑 | 编辑源代码]
使用指针数组模拟:
#include <stdlib.h>
int** create_2d_array(int rows, int cols) {
int **arr = (int**)malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++) {
arr[i] = (int*)malloc(cols * sizeof(int));
}
return arr;
}
void free_2d_array(int** arr, int rows) {
for(int i = 0; i < rows; i++) {
free(arr[i]);
}
free(arr);
}
数组与指针的关系[编辑 | 编辑源代码]
二维数组名是指向第一个子数组的指针:
int matrix[3][4];
int (*ptr)[4] = matrix; // 指向包含4个int的数组的指针
常见问题[编辑 | 编辑源代码]
页面模块:Message box/ambox.css没有内容。
数组越界访问是常见错误,C语言不会自动检查边界! |
- Q: 为什么不能省略所有维度?
- A: 编译器需要知道除第一维外的所有维度来计算内存布局
- Q: 如何传递多维数组给函数?
- A: 必须指定除第一维外的所有维度,如:
void func(int arr[][4])
最佳实践[编辑 | 编辑源代码]
- 对大型数组使用
static
存储类避免栈溢出 - 使用
#define
或const
定义维度常量 - 初始化时使用嵌套花括号提高可读性
- 考虑使用结构体封装复杂的多维数组