C++数组详解:一维和多维数组的定义、初始化、访问与遍历
1. 引言
数组是C++中最基础的数据结构之一,用于存储相同类型的元素的集合。它提供了高效的内存访问方式,适用于需要快速查找和遍历数据的场景。本文将全面介绍:
- 一维数组的定义、初始化与遍历
- 多维数组(如二维数组)的定义与使用
- 数组的常见操作与应用场景
- 数组与指针的关系
- C++11/17引入的现代数组特性(如
std::array
)
2. 一维数组
2.1 定义与声明
一维数组是线性存储的数据结构,所有元素在内存中连续排列。
语法
数据类型 数组名[数组长度]; // 静态数组
- 数据类型:可以是
int
、double
、char
等。 - 数组长度:必须是编译期常量(C++11后可用
constexpr
)。
示例:定义一个包含5个整数的数组
int numbers[5]; // 未初始化,值随机
2.2 初始化
数组可以在定义时初始化,也可以后续赋值。
方式1:直接初始化
int arr1[3] = {1, 2, 3}; // 完全初始化
int arr2[5] = {1, 2}; // 部分初始化,剩余元素为0
int arr3[] = {1, 2, 3}; // 自动推导长度为3
方式2:循环赋值
for (int i = 0; i < 5; i++) {numbers[i] = i * 2;
}
C++11统一初始化
int arr4[]{1, 2, 3}; // 省略等号
2.3 访问元素
通过下标运算符 []
访问,索引从 0
开始。
示例:读写数组元素
int first = arr1[0]; // 读取第一个元素
arr1[1] = 99; // 修改第二个元素
越界风险
C++不检查数组越界,访问 arr[5]
(长度为5时)会导致未定义行为(UB)。
2.4 遍历数组
方法1:传统for循环
for (int i = 0; i < 5; i++) {cout << numbers[i] << " ";
}
方法2:范围for循环(C++11)
for (int num : numbers) {cout << num << " ";
}
示例:计算数组元素和
int sum = 0;
for (int i = 0; i < 5; i++) {sum += numbers[i];
}
cout << "Sum: " << sum << endl;
3. 多维数组
3.1 二维数组的定义
二维数组是“数组的数组”,常用于表示矩阵或表格。
语法
数据类型 数组名[行数][列数];
示例:定义一个3x3矩阵
int matrix[3][3];
3.2 初始化多维数组
方式1:逐行初始化
int matrix[2][3] = {{1, 2, 3}, // 第一行{4, 5, 6} // 第二行
};
方式2:扁平化初始化
int matrix[2][3] = {1, 2, 3, 4, 5, 6}; // 按内存顺序
部分初始化
int matrix[2][3] = {{1}, {4}}; // 其余元素为0
3.3 访问与遍历
嵌套for循环遍历
for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++) {cout << matrix[i][j] << " ";}cout << endl;
}
示例:矩阵乘法
int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
int b[3][2] = {{7, 8}, {9, 10}, {11, 12}};
int result[2][2] = {0};for (int i = 0; i < 2; i++) {for (int j = 0; j < 2; j++) {for (int k = 0; k < 3; k++) {result[i][j] += a[i][k] * b[k][j];}}
}
4. 数组与指针
4.1 数组名的本质
数组名是首元素的地址(指针常量):
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // 等价于 &arr[0]
指针算术访问数组
cout << *(ptr + 2); // 输出arr[2]
4.2 数组作为函数参数
数组传递时会退化为指针,需额外传递长度。
值传递(实际是指针传递)
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {cout << arr[i] << " ";}
}
引用传递(C++)
void printArray(int (&arr)[5]) { // 必须指定长度for (int num : arr) {cout << num << " ";}
}
5. 现代C++数组(std::array)
5.1 std::array 的优势
- 固定大小:编译期确定长度。
- 边界检查:通过
at()
方法检查越界。 - 支持迭代器:兼容STL算法。
定义与初始化
#include <array>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
安全访问
cout << arr.at(2); // 越界时抛出std::out_of_range
6. 应用场景
6.1 一维数组应用
- 统计数据分析:计算平均值、最大值。
- 排序算法:实现冒泡排序、快速排序。
// 冒泡排序示例
void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {swap(arr[j], arr[j+1]);}}}
}
6.2 多维数组应用
- 图像处理:像素矩阵操作。
- 游戏开发:地图网格表示。
// 迷宫路径查找(简化版)
bool findPath(int maze[5][5], int x, int y) {if (x < 0 || y < 0 || x >= 5 || y >= 5 || maze[x][y] == 1) {return false;}maze[x][y] = 1; // 标记已访问return findPath(maze, x+1, y) || findPath(maze, x, y+1);
}
7. 总结与最佳实践
7.1 关键点总结
特性 | 一维数组 | 多维数组 | std::array |
---|---|---|---|
定义 | int arr[5]; | int arr[3][3]; | std::array<int,5> arr; |
初始化 | {1,2,3} | {{1,2},{3,4}} | ={1,2,3} |
越界检查 | 无 | 无 | at() 方法 |
推荐场景 | 简单数据集合 | 矩阵/表格 | 需要安全性和STL集成 |
7.2 最佳实践
- 优先使用
std::array
:比原生数组更安全。 - 避免越界:手动检查索引,或使用
at()
。 - 传递数组时附带长度:防止函数内越界。
- 多维数组的内存布局:按行存储,遍历时优先考虑缓存局部性。
8. 结语
数组是C++中最基础且高效的数据结构,适用于各种场景。本文详细介绍了:
- 一维和多维数组的定义、初始化与遍历
- 数组与指针的关系
- 现代C++的
std::array
用法 - 实际应用案例(排序、矩阵运算)
下一步学习:探索动态数组(std::vector
)和更复杂的容器(如 std::map
)。