010 C++的数组(Array)
作者Lou Xiao, deepseek创建时间2025-04-02 07:17:29更新时间2025-04-02 07:17:29
1. 数组基础概念
1.1 什么是数组
- 数组是相同类型元素的集合,存储在连续的内存位置中
- 每个元素可以通过索引(下标)访问
- 数组大小在创建时固定,不能动态改变
1.2 数组特性
- 固定大小:一旦声明,大小不能改变
- 连续内存:元素在内存中连续存储
- 同质元素:所有元素必须是相同类型
- 高效访问:通过索引直接访问,时间复杂度O(1)
2. 数组声明与初始化
2.1 声明语法
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
type arrayName[arraySize];
示例:
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int numbers[5]; // 声明一个包含5个整数的数组
2
double prices[10]; // 声明一个包含10个双精度浮点数的数组
2.2 初始化方式
2.2.1 静态初始化
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr1[5] = {1, 2, 3, 4, 5}; // 完全初始化
2
int arr2[5] = {1, 2, 3}; // 部分初始化,剩余元素为0
3
int arr3[] = {1, 2, 3, 4, 5}; // 自动推断大小为5
2.2.2 动态初始化
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5];
2
for(int i = 0; i < 5; i++) {
3
arr[i] = i * 2;
4
}
2.2.3 C++11统一初始化
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr1[]{1, 2, 3, 4, 5}; // 省略等号
2
int arr2[5]{}; // 全部初始化为0
3. 数组操作
3.1 访问元素
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5] = {10, 20, 30, 40, 50};
2
cout << arr[0]; // 输出第一个元素(10)
3
arr[2] = 100; // 修改第三个元素
3.2 遍历数组
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
// 方法1:使用for循环
2
for(int i = 0; i < 5; i++) {
3
cout << arr[i] << " ";
4
}
5
6
// 方法2:使用范围for循环(C++11)
7
for(int num : arr) {
8
cout << num << " ";
9
}
3.3 多维数组
3.3.1 二维数组声明
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int matrix[3][4]; // 3行4列的二维数组
3.3.2 二维数组初始化
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int matrix[2][3] = {
2
{1, 2, 3},
3
{4, 5, 6}
4
};
3.3.3 访问多维数组元素
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
matrix[1][2] = 10; // 访问第二行第三列的元素
4. 数组与指针的关系
4.1 数组名是指向首元素的指针
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5] = {1, 2, 3, 4, 5};
2
int* ptr = arr; // 等价于 int* ptr = &arr[0];
4.2 指针算术访问数组元素
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
cout << *(ptr + 2); // 等价于 arr[2]
4.3 数组作为函数参数
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void printArray(int arr[], int size) {
2
for(int i = 0; i < size; i++) {
3
cout << arr[i] << " ";
4
}
5
}
6
7
// 调用
8
printArray(arr, 5);
5. C++标准库数组(std::array)
5.1 std::array介绍
- C++11引入的容器类模板
- 提供比原始数组更多的功能和安全性
- 包含在
头文件中
5.2 std::array基本用法
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
#include <array>
2
#include <iostream>
3
4
int main() {
5
std::array<int, 5> arr = {1, 2, 3, 4, 5};
6
7
// 访问元素
8
std::cout << arr.at(2) << std::endl; // 带边界检查
9
std::cout << arr[3] << std::endl; // 不带边界检查
10
11
// 获取大小
12
std::cout << "Size: " << arr.size() << std::endl;
13
14
// 遍历
15
for(int num : arr) {
16
std::cout << num << " ";
17
}
18
19
return 0;
20
}
5.3 std::array vs 原始数组
特性 | std::array | 原始数组 |
---|---|---|
大小 | 固定,编译时确定 | 固定,编译时确定 |
边界检查 | 有(at()方法) | 无 |
作为参数传递 | 按值传递(不退化) | 退化为指针 |
大小获取 | size()方法 | 需要额外变量或sizeof |
赋值 | 支持整体赋值 | 不支持 |
迭代器支持 | 有 | 无 |
6. 常见数组算法
6.1 查找
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
// 线性查找
2
int linearSearch(int arr[], int size, int key) {
3
for(int i = 0; i < size; i++) {
4
if(arr[i] == key) {
5
return i;
6
}
7
}
8
return -1;
9
}
6.2 排序
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
// 冒泡排序
2
void bubbleSort(int arr[], int size) {
3
for(int i = 0; i < size-1; i++) {
4
for(int j = 0; j < size-i-1; j++) {
5
if(arr[j] > arr[j+1]) {
6
swap(arr[j], arr[j+1]);
7
}
8
}
9
}
10
}
6.3 反转数组
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void reverseArray(int arr[], int size) {
2
int start = 0;
3
int end = size - 1;
4
while(start < end) {
5
swap(arr[start], arr[end]);
6
start++;
7
end--;
8
}
9
}
7. 数组的局限性与替代方案
7.1 局限性
- 固定大小,无法动态调整
- 缺乏边界检查
- 传递时会退化为指针
- 不支持直接赋值和比较
7.2 替代方案
- std::vector:动态数组,大小可变
- std::array:固定大小但更安全的数组
- std::valarray:数值计算优化的数组
8. 最佳实践
- 优先使用std::array而不是原始数组
- 需要动态大小时使用std::vector
- 传递数组时同时传递大小信息
- 使用范围for循环简化遍历
- 对性能关键代码,考虑原始数组的潜在优势
9. 常见错误
- 数组越界访问
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5];
2
arr[5] = 10; // 越界访问
- 忘记初始化数组
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[5];
2
// 使用未初始化的数组元素
- 数组大小计算错误
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
int arr[] = {1, 2, 3};
2
int size = sizeof(arr); // 错误,应该是sizeof(arr)/sizeof(arr[0])
- 数组作为函数参数时大小信息丢失
1.双击鼠标左键复制此行;2.单击复制所有代码。
1
void func(int arr[]) {
2
// 无法在这里获取数组实际大小
3
}
10. 性能考虑
- 数组访问非常快(O(1)时间复杂度)
- 连续内存布局有利于缓存利用
- 多维数组的行优先存储顺序影响性能
- 固定大小数组可能被编译器优化得更好
文章目录