模块二 · 流程与数据 / 第 09 课
09 · 数组
学习目标
- 会定义和访问数组
- 知道下标从 0 开始
- 会遍历数组求和、找最大值
定义与访问
#include <stdio.h>
int main(void)
{
int a[5]; /* 5 个 int,下标 0..4 */
int i;
for (i = 0; i < 5; i++)
{
a[i] = i * 10;
}
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
下标从 0 开始
长度为 5 的数组,合法下标是 0,1,2,3,4。访问 a[5] 是越界,结果未定义,可能乱改别的内存。
纪律
遍历统一写 for (i = 0; i < n; i++),不要写 <= n。初始化与求和
#include <stdio.h>
int main(void)
{
int a[4] = {1, 2, 3, 4};
int sum = 0;
int i;
for (i = 0; i < 4; i++)
{
sum = sum + a[i];
}
printf("sum = %d\n", sum); // 10
return 0;
}
找最大值(必会套路)
#include <stdio.h>
int main(void)
{
int a[5] = {12, 45, 7, 88, 23};
int max = a[0]; /* 先假设第一个最大 */
int i;
for (i = 1; i < 5; i++)
{
if (a[i] > max)
{
max = a[i];
}
}
printf("max = %d\n", max); // 88
return 0;
}
从键盘填入数组
#include <stdio.h>
#define N 3
int main(void)
{
int a[N];
int i;
printf("请输入 %d 个整数:\n", N);
for (i = 0; i < N; i++)
{
scanf("%d", &a[i]); /* 注意 &a[i] */
}
for (i = 0; i < N; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
二维数组(了解)
可以理解成「表格」:3 行 4 列。
int m[3][4]; /* 3 行 4 列 */
m[0][0] = 1; /* 第0行第0列 */
/* 双重循环遍历:外层行、内层列 */
单片机场景 · 数组:采样数据与查找表
数组把同类型数据放在一起,读写前先确认下标范围。
边界与验证:table[0] 是第一个元素,table[2] 是第三个。修改第一个元素不影响第三个。
unsigned char table[5] = {10, 20, 30, 40, 50};
unsigned char x;
table[0] = 99;
x = table[2];
本课过关
必做int a[3] 的合法下标是?
逐步解析
C 里数组下标从 0 开始编号。int a[3] 表示分配 3 个连续 int:下标分别是 0、1、2。访问 a[3] 已经越出这 3 个位置,属于未定义行为——可能读到垃圾值,也可能改坏相邻变量。不要把「长度 3」理解成「下标到 3」。安全写法:遍历时写 for (i = 0; i < 3; i++),用「小于长度」而不是「小于等于最大下标」,以后改长度也不容易错。
必做作业
- 定义长度 6 的数组,全部填 0。
- 存 5 个成绩,打印最高分。
- 越界访问 a[10] 可能发生什么?
- 把找最大值改成同时打印最大值的下标。
先自己写完,再点开看解答
1:全 0 数组 int a[6] = {0}; 只写出第一个 0,其余自动为 0。
2:5 个成绩的最高分
int scores[5] = {70, 88, 55, 90, 62};
int max = scores[0], i;
for (i = 1; i < 5; i++)
if (scores[i] > max) max = scores[i];
printf("%d\n", max);3:越界后果:a[10] 已不在合法 0..9 内。可能读到别的变量,或写坏别人的内存,表现为「我没改它却变了」的诡异 bug。这类错误往往不能稳定复现。
4:同时记下标:比较成功时除了 max=…,再写 idx=i;最后打印 idx。
学完去哪
下一课:把重复代码收拢成函数。