C++: 数组基础
最后更新:2026-08-26
前面的课程里,每个变量只能存一个值。
但如果你要存 100 个学生的成绩,总不能声明 100 个变量吧?
数组就是解决这个问题——一片连续的内存空间,用来存多个同类型的数据。
1. 什么是数组?
(1) 1.1 生活中的数组
| 生活场景 | 程序中的对应 |
|---|---|
| 一排信箱(每个信箱编号不同) | 数组(每个元素下标不同) |
| 一盒鸡蛋(12 个,编号 1-12) | 数组(12 个元素,下标 0-11) |
数组的特点:
- 所有元素类型相同(都是
int,或都是double) - 内存连续(元素一个挨一个)
- 下标从 0 开始(不是从 1 开始!)
(2) 1.2 为什么需要数组?
不用数组(坏例子):
▶ 示例 2:基础编程实践(难度⭐)
#include <iostream>
int main() {
int score1 = 90;
int score2 = 85;
int score3 = 92;
// ... need to declare 100 variables!
return 0;
}
输出:
(程序输出)
用数组(好例子):
#include <iostream>
int main() {
int scores[100]; // array that can hold 100 integers
// use loop to assign values
for (int i = 0; i < 100; i++) {
scores[i] = 0;
}
return 0;
}
2. 数组的声明与初始化
(1) 2.1 声明数组
语法:
类型 数组名[元素个数];
示例:
int scores[5]; // array that can hold 5 integers
double prices[10]; // array that can hold 10 doubles
char letters[26]; // array that can hold 26 chars
💡 重点: 数组的下标从 0 开始,所以 scores[5] 的下标范围是 0 到 4(不是 1 到 5)。
(2) 2.2 初始化数组
方法一:声明时初始化
int scores[5] = {90, 85, 92, 78, 88};
方法二:部分初始化
int scores[5] = {90, 85}; // only initialize first two, rest become 0 automatically
方法三:让编译器推断大小
int scores[] = {90, 85, 92, 78, 88}; // compiler infers size as 5
💡 提示: 推荐用方法三,这样如果以后改了数组内容,不用手动改大小。
3. 访问数组元素
(1) 3.1 读取元素
语法:
数组名[下标]
示例:
#include <iostream>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
std::cout << "第一个成绩:" << scores[0] << std::endl; // 90
std::cout << "第三个成绩:" << scores[2] << std::endl; // 92
std::cout << "最后一个成绩:" << scores[4] << std::endl; // 88
return 0;
}
(2) 3.2 修改元素
#include <iostream>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
scores[1] = 95; // change second score to 95
std::cout << "修改后的第二个成绩:" << scores[1] << std::endl; // 95
return 0;
}
4. 遍历数组
(1) 4.1 用 for 循环遍历
#include <iostream>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
std::cout << "所有成绩:" << std::endl;
for (int i = 0; i < 5; i++) {
std::cout << "第 " << i + 1 << " 个成绩:" << scores[i] << std::endl;
}
return 0;
}
💡 重点: 遍历数组时,循环条件通常是 i < 数组大小,而不是 i <= 数组大小 - 1(这样容易出错)。
5. 数组的大小
(1) 5.1 用 sizeof 计算元素个数
#include <iostream>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
int size = sizeof(scores) / sizeof(scores[0]); // calculate array size
std::cout << "数组大小:" << size << std::endl; // 5
return 0;
}
原理:
sizeof(scores)— 整个数组占的字节数(5 × 4 = 20 字节)sizeof(scores[0])— 一个元素占的字节数(4 字节)- 相除得到元素个数
💡 提示: 这个方法只适用于真正的数组,不适用于指针(后面会学)。
6. 数组作为函数参数
(1) 6.1 问题:数组会退化成指针
当你把数组传给函数时,数组会退化成指针(丢失大小信息)。
#include <iostream>
// array as parameter, need to pass size
void printArray(int arr, int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
int main() {
int scores[5] = {90, 85, 92, 78, 88};
printArray(scores, 5); // pass array name (which is address of first element)
return 0;
}
💡 重点: 数组作为参数时,必须额外传一个大小参数。
7. 常见错误
(1) 7.1 数组越界
错误示例:
#include <iostream>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
std::cout << scores[5] << std::endl; // ERROR: out of bounds! max index is 4
return 0;
}
后果: 读取垃圾值,或者程序崩溃。
💡 提示: C++ 不会自动检查数组越界!这是 C++ 速度快的原因之一,但也是常见的 bug 来源。
(2) 7.2 用变量作为数组大小(C++11 之前)
错误示例(C++11 之前):
#include <iostream>
int main() {
int n = 5;
int scores[n]; // ERROR (before C++11): array size must be compile-time constant
return 0;
}
正确写法(C++11 之后支持):
#include <iostream>
int main() {
int n = 5;
int scores[n]; // OK (after C++11): Variable Length Array (VLA) supported
return 0;
}
💡 更好的方法: 用 std::vector(后面会学),它支持动态大小。
8. 实战:计算平均分
▶ 示例 1:计算平均分(难度⭐⭐)
#include <iostream>
#include <iomanip>
int main() {
int scores[5] = {90, 85, 92, 78, 88};
int sum = 0;
// calculate total score
for (int i = 0; i < 5; i++) {
sum += scores[i];
}
// calculate average score
double average = static_cast<double>(sum) / 5;
std::cout << std::fixed << std::setprecision(2);
std::cout << "总分:" << sum << std::endl;
std::cout << "平均分:" << average << std::endl;
return 0;
}
输出:
总分:433
平均分:86.60
❓ 常见问题
▶ 示例 3:数组遍历(难度⭐)
#include <iostream>
int main() {
int scores[] = {85, 92, 78, 90, 88};
int sum = 0;
for (int i = 0; i < 5; i++) {
sum += scores[i];
}
double avg = sum / 5.0;
std::cout << "平均分:" << avg << std::endl;
return 0;
}
输出:
平均分:86.6
{} 初始化,元素个数可以用 sizeof(arr) / sizeof(arr[0]) 计算。
📖 小节
- 数组是一片连续的内存空间,用来存多个同类型的数据
- 数组的下标从 0 开始
- 声明数组:
类型 数组名[大小]; - 初始化数组:
类型 数组名 = {值1, 值2, ...}; - 访问元素:
数组名[下标] - 遍历数组:用
for循环 - 数组作为参数时会退化成指针,需要额外传大小
📝 作业
-
基础题 (Difficulty ⭐): 声明一个
double数组,存 5 个价格,用循环计算总价。 -
进阶题 (Difficulty ⭐⭐): 写一个函数
int findMax(int arr, int size),找出数组的最大值。 在main里测试。 -
挑战题 (Difficulty ⭐⭐⭐): 写一个程序,让用户输入 10 个整数,存到数组里,然后:
-
找出最大值和最小值
-
计算平均分
-
输出所有高于平均分的成绩
- 数组:相同类型元素的连续内存集合
- 下标从 0 开始,声明时必须指定大小
- 数组初始化列表 { } 可省略大小
- 遍历数组用 for 循环配合下标
- 数组名是首元素地址,不可修改
9. 🚀 下一步
学会了数组基础,接下来我们学习 多维数组(第17课)—— 处理表格数据(如矩阵、棋盘)。