第24章 一维数组

第24章 一维数组

GESP 三级定位
等级知识块考查频率
GESP C++ 三级一维数组基本应用⭐⭐⭐

当需要处理多个同类型数据时,逐个用变量存储既繁琐又低效。一维数组提供连续存储、按索引访问的能力,是处理批量数据最重要的工具之一。三级要求掌握其定义、初始化、遍历与常见应用。

24.1 一维数组的基本概念

一维数组是由相同类型元素组成的有序集合,元素在内存中连续存储,通过唯一的索引(下标)定位。索引从 0 开始依次递增:长度为 5 的数组,下标为 0、1、2、3、4。

一维数组在内存中连续存储

24.2 一维数组的定义

24.2.1 定义语法

数据类型 数组名[长度];
  • 数据类型:所有元素统一类型(int、float、char 等)
  • 数组名:符合标识符命名规范
  • 长度:必须是常量/常量表达式,不能是变量
array_define.cpp
int scores[5]; // 存放 5 个整数
float weights[10]; // 存放 10 个浮点数
char letters[26]; // 存放 26 个字符
长度必须是常量

int n = 5; int a[n]; 在 C++ 标准里属于「变长数组(VLA)」,不是标准 C++,很多竞赛编译器(开启严格标准)会报错。竞赛中要么用常量,要么用 vector。三级一般使用常量长度即可。

24.3 一维数组的初始化

24.3.1 完全初始化

全部赋值,可省略长度,编译器自动推算:

array_init_full.cpp
int a[5] = {1, 2, 3, 4, 5};
int b[] = {6, 7, 8}; // 自动推断长度为 3

24.3.2 部分初始化

只给前若干元素赋值,剩余数值型元素自动补 0,char 补 \0:

array_init_partial.cpp
int c[5] = {10, 20}; // c[0]=10, c[1]=20, c[2..4]=0
char d[4] = {'A', 'B'}; // d[0]='A', d[1]='B', d[2..3]='\0'
全局数组默认全 0

定义在函数外的数组(全局/静态)未初始化时默认全 0;但局部数组(函数内)不初始化会得到随机垃圾值,务必初始化。

24.4 元素的访问与修改

访问格式:数组名[下标],有效范围 0≤下标≤长度−10 \le \text{下标} \le \text{长度}-1。

array_access.cpp
int arr[3] = {100, 200, 300};
cout << arr[0]; // 输出 100
cout << arr[2]; // 输出 300

float values[2] = {3.14, 1.59};
values[1] = 2.71; // 修改
cout << values[1]; // 输出 2.71

24.5 数组长度计算

用 sizeof:总字节数 ÷ 单个元素字节数 = 元素个数。

array_len.cpp
int numbers[5] = {1, 2, 3, 4, 5};
int len = sizeof(numbers) / sizeof(numbers[0]); // 5
函数参数会退化成指针

数组作为函数参数传递时会退化为指针,此时 sizeof 只能得到指针大小(通常 8 字节),无法求长度。必须额外传长度参数!

void printArr(int a[], int n) { // n 必须显式传入
for (int i = 0; i < n; i++) cout << a[i] << " ";
}

24.6 常见应用场景

场景1:批量存储

scenario_store.cpp
int scores[30]; // 存储班级 30 人成绩

场景2:求和、最值

scenario_sum.cpp
int arr[4] = {5, 3, 8, 2};
int sum = 0, mx = arr[0];
for (int i = 0; i < 4; i++) {
sum += arr[i];
if (arr[i] > mx) mx = arr[i];
}
// sum = 18, mx = 8

场景3:选择排序

selection_sort.cpp
int nums[5] = {3, 1, 4, 2, 5};
int n = 5;
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (nums[j] < nums[minIdx]) minIdx = j;
}
int temp = nums[i]; nums[i] = nums[minIdx]; nums[minIdx] = temp;
}

24.7 使用注意事项

  1. 数组越界:下标超出 0~len−1 会读写未知内存,导致崩溃或数据错乱(C++ 不自动检查);
  2. 局部数组未初始化:值是随机垃圾;
  3. 数组名是常量地址,不可整体赋值:int a[5]; a = {1,2}; 语法错误;
  4. 变长数组非标准 C++,竞赛慎用。
越界是 C++ 头号坑

int a[5]; a[5] = 10; 看似"只多一位",实则写入了不属于数组的内存,可能悄悄破坏其他变量,且编译器通常不报错。务必保证下标 < 长度。

24.8 选择题练习

1. 定义 int a[5];,合法的数组元素是?

A. a[1]、a[5]
B. a[0]、a[4]
C. a[-1]、a[0]
D. a[0]、a[5]

点击展开参考答案与解析

答案:B

解析:长度为 5 的数组,下标合法范围是 0~4,a[5] 越界、a[-1] 也越界,选 B。

2. 关于 int b[] = {1, 2, 3};,下列说法正确的是?

A. 数组长度为 3,由编译器推断
B. 数组长度为 0
C. 必须写成 int b[3]
D. 未初始化的元素为随机值

点击展开参考答案与解析

答案:A

解析:省略长度时编译器按初值个数推断为 3,选 A。部分初始化未给的元素补 0。

3. int c[5] = {10}; 执行后,c[1] 的值是?

A. 10
B. 0
C. 随机值
D. 编译错误

点击展开参考答案与解析

答案:B

解析:只给 c[0]=10,其余元素自动补 0,故 c[1]=0,选 B。

4. 在 32 位/64 位普遍环境下,int a[5]; 用 sizeof(a)/sizeof(a[0]) 得到?

A. 5
B. 20
C. 8
D. 不确定

点击展开参考答案与解析

答案:A

解析:int 占 4 字节,a 总字节 20,20/4=5,选 A(与平台位数无关,因为 sizeof(a) 是整个数组)。

5. 把数组传给函数 void f(int x[]),在函数内用 sizeof(x) 求长度,结果是?

A. 数组真实长度
B. 指针的大小(如 8)
C. 编译错误
D. 0

点击展开参考答案与解析

答案:B

解析:数组作参数退化为指针,sizeof(x) 得到指针大小(64 位下 8),不是数组长度,选 B。所以必须额外传长度参数。

SShowball OI知识手册