跳转至

一维数组

数组的定义

一组相同类型的数据,可以放进数组里,按编号访问。

int a[110];

开了一个名字叫小 a 的数组,可以存 110 个 int。这些元素在内存中连续存放。

数组开多大?

看题目最多有多少个数据,再看下标从哪里开始。

100 个数据,从 0 开始存,用到 a[0] 到 a[99];从 1 开始存,用到 a[1] 到 a[100]。

做题时,通常留一点余量,开 a[110]。但多开几个位置,不代表可以随意访问。

数组的访问,下标

数组下标从 0 开始。

int a[5] = {10, 20, 30, 40, 50};
cout << a[0]; // 第一个元素,10
cout << a[4]; // 最后一个元素,50

a[2] = 99;   // 把第三个元素改成99

a[i] 表示下标为 i 的元素,不能把“第几个”和“下标”混了。

从 1 开始存,也是可以的。

这是我们选择不用 a[0],不是数组的下标规则变了。

数组的初始化

数组开全局

做题时,数组一般开在 main 外面。没有另外初始化的全局数组,元素默认都是 0。

int a[110]; // 全局数组,元素默认是0

int main() {
    // ...
}

普通局部数组不一样:写在函数里面,没有初始化,就不能直接读取它的值。

int a[110] = {}; // 局部数组也可以这样,全部初始化为0

使用大括号初始化

int a[] = {0, 1, 2, 3, 4}; // 省略长度,自动得到5个元素
int a[10] = {0, 1, 2, 3, 4}; // 前5个按列表初始化,后5个是0

数组的输入输出

这里 0 <= n <= 100,从下标 0 开始存。

#include <iostream>

using namespace std;

int a[110];

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    for (int i = 0; i < n; i++) cout << a[i] << ' ';

    return 0;
}

数组的遍历

遍历,就是把需要处理的元素,一个一个访问一遍。

从左向右

for (int i = 0; i < n; i++) cout << a[i] << ' ';

从右向左

for (int i = n - 1; i >= 0; i--) cout << a[i] << ' ';

用常量开数组

多个数组需要相同的容量,用常量统一写,避免多写、少写一个 0。

const int N = 1e5 + 10;
int a[N], b[N];

const 表示这里的 N 是常量,定义后不能重新赋值。

常用数组名称

数组名称 单词全拼 使用场景
a[]、arr[] array 通用数组名
cnt[] count 计数数组
dis[]、d[] distance 距离、步数
vis[]、st[] visited、state 是否访问过、状态
s[] string 字符数组

常见错误

数组越界

int a[10]; 的有效下标是 0 到 9,a[-1]、a[10] 都越界。

越界不一定立刻报错,也可能悄悄产生错误结果,不能靠“运行没崩溃”判断对错。

数组长度,不直接用读入的 n

int n;
cin >> n;
int a[n]; // 先不要这样写,不是标准C++的数组定义方式

本阶段按题目上限,用常量开数组。不要把“编译器碰巧支持”当成通用写法。

容量与实际个数,不是一回事。

开了 a[110],只输入了 n 个数,处理数据时就按 n 遍历,不是把 110 个位置都算进去。

数组不能直接整体赋值。

不能用 a = b; 复制两个普通数组,要循环逐个复制对应元素。

memset(先不看)

需要头文件 <cstring>。

memset(a, 0, sizeof a); // 将整个数组清零

sizeof a 是整个数组占用的字节数,不是元素个数。这里的 a 要是数组本身。

常见环境中,对 int 数组还会看到:

memset(a, -1, sizeof a);   // 每个元素设成-1
memset(a, 0x3f, sizeof a); // 32位int中,每个元素变成0x3f3f3f3f

0x3f3f3f3f 常用作一个较大的初始值,不是 int 的最大值。

memset 按字节填充。 不能写 memset(a, 1, sizeof a),就认为每个整数都变成 1。

想把每个元素设成 1,可以用循环逐个赋值。原理等学过二进制后,再看memset。