C++一维数组 #
一、数组概述 #
数组是存储相同类型元素的连续内存空间。
1.1 数组特点 #
- 元素类型相同
- 内存连续
- 大小固定
- 通过下标访问
1.2 数组声明 #
cpp
// 语法:type name[size];
int arr[5]; // 声明包含5个int的数组
double prices[10]; // 声明包含10个double的数组
char name[20]; // 声明包含20个char的数组
二、数组初始化 #
2.1 完全初始化 #
cpp
int arr[5] = {1, 2, 3, 4, 5};
// 使用花括号初始化(C++11)
int arr2[5] {1, 2, 3, 4, 5};
2.2 部分初始化 #
cpp
// 未指定的元素自动初始化为0
int arr[5] = {1, 2}; // {1, 2, 0, 0, 0}
2.3 省略大小 #
cpp
// 编译器自动推断大小
int arr[] = {1, 2, 3, 4, 5}; // 大小为5
2.4 零初始化 #
cpp
int arr[5] = {0}; // {0, 0, 0, 0, 0}
int arr2[5] = {}; // {0, 0, 0, 0, 0}
2.5 常量数组 #
cpp
const int arr[5] = {1, 2, 3, 4, 5}; // 不可修改
三、数组访问 #
3.1 下标访问 #
cpp
int arr[5] = {10, 20, 30, 40, 50};
// 读取元素
std::cout << arr[0] << std::endl; // 10
std::cout << arr[2] << std::endl; // 30
// 修改元素
arr[0] = 100;
arr[4] = 500;
3.2 下标范围 #
cpp
int arr[5];
// 有效下标:0 到 4
arr[0] = 1; // 第一个元素
arr[4] = 5; // 最后一个元素
// 越界访问(未定义行为)
arr[5] = 6; // 危险!越界
arr[-1] = 0; // 危险!越界
3.3 遍历数组 #
cpp
int arr[5] = {1, 2, 3, 4, 5};
// 使用for循环
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
// 使用范围for(C++11)
for (int x : arr) {
std::cout << x << " ";
}
// 使用引用修改
for (int& x : arr) {
x *= 2; // 每个元素乘以2
}
四、数组大小 #
4.1 使用sizeof #
cpp
int arr[5] = {1, 2, 3, 4, 5};
// 数组总字节数
size_t totalBytes = sizeof(arr); // 20 (5 * 4)
// 单个元素字节数
size_t elementBytes = sizeof(arr[0]); // 4
// 元素个数
size_t count = sizeof(arr) / sizeof(arr[0]); // 5
4.2 使用std::size(C++17) #
cpp
#include <iterator>
int arr[5] = {1, 2, 3, 4, 5};
size_t count = std::size(arr); // 5
4.3 使用模板函数 #
cpp
template<typename T, size_t N>
constexpr size_t arraySize(T (&)[N]) {
return N;
}
int arr[5];
size_t count = arraySize(arr); // 5
五、数组与函数 #
5.1 传递数组给函数 #
cpp
// 数组作为参数时退化为指针
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr, 5);
return 0;
}
5.2 使用指针参数 #
cpp
void printArray(int* arr, int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
}
5.3 使用模板保留数组大小 #
cpp
template<size_t N>
void printArray(int (&arr)[N]) {
for (int i = 0; i < N; i++) {
std::cout << arr[i] << " ";
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr); // 不需要传递大小
return 0;
}
5.4 使用std::array(推荐) #
cpp
#include <array>
void printArray(const std::array<int, 5>& arr) {
for (int x : arr) {
std::cout << x << " ";
}
}
六、数组操作 #
6.1 查找元素 #
cpp
int arr[5] = {10, 20, 30, 40, 50};
int target = 30;
int index = -1;
for (int i = 0; i < 5; i++) {
if (arr[i] == target) {
index = i;
break;
}
}
if (index != -1) {
std::cout << "找到元素,索引: " << index << std::endl;
}
6.2 求和与平均值 #
cpp
int arr[5] = {10, 20, 30, 40, 50};
int sum = 0;
for (int x : arr) {
sum += x;
}
double average = static_cast<double>(sum) / 5;
std::cout << "总和: " << sum << std::endl;
std::cout << "平均值: " << average << std::endl;
6.3 找最大最小值 #
cpp
int arr[5] = {30, 10, 50, 20, 40};
int maxVal = arr[0];
int minVal = arr[0];
for (int i = 1; i < 5; i++) {
if (arr[i] > maxVal) maxVal = arr[i];
if (arr[i] < minVal) minVal = arr[i];
}
std::cout << "最大值: " << maxVal << std::endl;
std::cout << "最小值: " << minVal << std::endl;
6.4 数组复制 #
cpp
int source[5] = {1, 2, 3, 4, 5};
int dest[5];
// 手动复制
for (int i = 0; i < 5; i++) {
dest[i] = source[i];
}
// 使用std::copy
#include <algorithm>
std::copy(std::begin(source), std::end(source), std::begin(dest));
// 使用memcpy
#include <cstring>
std::memcpy(dest, source, sizeof(source));
6.5 数组排序 #
cpp
#include <algorithm>
int arr[5] = {30, 10, 50, 20, 40};
// 升序排序
std::sort(std::begin(arr), std::end(arr));
// arr = {10, 20, 30, 40, 50}
// 降序排序
std::sort(std::begin(arr), std::end(arr), std::greater<int>());
// arr = {50, 40, 30, 20, 10}
七、变长数组 #
7.1 使用变量定义大小(非标准) #
cpp
int n = 5;
int arr[n]; // 非标准C++,但某些编译器支持
// 推荐:使用常量
const int N = 5;
int arr2[N]; // 标准C++
7.2 使用动态数组 #
cpp
int n = 5;
int* arr = new int[n]; // 动态分配
// 使用
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
// 释放
delete[] arr;
7.3 使用std::vector(推荐) #
cpp
#include <vector>
int n = 5;
std::vector<int> arr(n); // 大小可变
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
八、数组常见错误 #
8.1 越界访问 #
cpp
int arr[5] = {1, 2, 3, 4, 5};
// 危险:越界访问
std::cout << arr[5] << std::endl; // 未定义行为
std::cout << arr[-1] << std::endl; // 未定义行为
// 安全访问
int index = 5;
if (index >= 0 && index < 5) {
std::cout << arr[index] << std::endl;
}
8.2 数组退化 #
cpp
void func(int arr[]) {
// sizeof(arr) 是指针大小,不是数组大小
std::cout << sizeof(arr) << std::endl; // 8(64位系统)
}
int main() {
int arr[5];
std::cout << sizeof(arr) << std::endl; // 20
func(arr); // 数组退化为指针
}
8.3 未初始化 #
cpp
int arr[5]; // 未初始化,元素值不确定
// 推荐:始终初始化
int arr2[5] = {}; // 全部初始化为0
九、std::array(C++11) #
9.1 基本使用 #
cpp
#include <array>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// 访问元素
std::cout << arr[0] << std::endl;
std::cout << arr.at(0) << std::endl; // 带边界检查
// 获取大小
std::cout << arr.size() << std::endl;
// 遍历
for (int x : arr) {
std::cout << x << " ";
}
9.2 std::array vs 原生数组 #
| 特性 | 原生数组 | std::array |
|---|---|---|
| 大小获取 | sizeof计算 | size()方法 |
| 边界检查 | 无 | at()方法 |
| 赋值 | 不能直接赋值 | 可以直接赋值 |
| 作为参数 | 退化为指针 | 保留大小 |
十、总结 #
数组要点 #
| 操作 | 语法 |
|---|---|
| 声明 | type name[size] |
| 初始化 | {v1, v2, ...} |
| 访问 | arr[index] |
| 大小 | sizeof(arr)/sizeof(arr[0]) |
| 遍历 | for (int x : arr) |
最佳实践 #
- 始终初始化数组
- 避免越界访问
- 使用std::array代替原生数组
- 使用std::vector处理动态大小
下一步,让我们学习多维数组!
最后更新:2026-03-26