基础

C++ 数组:完整图景

一句话答案:int a[5] 保留五个连续的 int 位置,命名为 a[0] … a[4]。长度在编译时固定,而 C++ 不会在运行时检查你的下标。

内存是一排,不是网格

数组是一整块连续内存。a[3] 不是按名字查表 —— 它是「块首地址 + 三个元素宽度的字节」。这就是下标访问是 O(1) 的原因:一次乘法、一次加法。

#include <iostream>
using namespace std;

int main() {
    int a[5] = {10, 20, 30, 40, 50};

    cout << "first:  " << a[0] << endl;
    cout << "third:  " << a[2] << endl;
    cout << "last:   " << a[4] << endl;
    return 0;
}

并不存在 a[5]。写出来能编译、能运行,读到的只是内存里紧挨着的下一个东西 —— 那是未定义行为,不是一条错误信息。

为什么从 0 开始

因为下标本质是偏移量。第一个元素距离块首是零格。从 1 开始的语文要在每次访问前减一;C++ 把这次减法转移到了你的代码里,于是运行时免费。

开多大:取上限,而不是精确值

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int a[100];                 // 开一个上限
    for (int i = 0; i < n; i++) cin >> a[i];

    cout << "read " << n << " values" << endl;
    return 0;
}

C++ 数组不能改大小。真实代码里要么开一个宽裕的上限(如上),要么用会自动增长的 std::vector。两者对比见vector 与数组。

值得背下来的三个模式

1. 求和 —— 累加器初始化为零。

#include <iostream>
using namespace std;

int main() {
    int a[5] = {1, 2, 3, 4, 5};
    int sum = 0;
    for (int i = 0; i < 5; i++) sum += a[i];
    cout << sum << endl;   // 15
    return 0;
}

2. 求最大 —— 用第一个元素做种子,绝不用 0。

#include <iostream>
using namespace std;

int main() {
    int a[4] = {-9, -3, -7, -1};
    int best = a[0];
    for (int i = 1; i < 4; i++) {
        if (a[i] > best) best = a[i];
    }
    cout << best << endl;   // -1,不是 0
    return 0;
}

3. 计数 —— 每类一个计数器。

#include <iostream>
using namespace std;

int main() {
    int a[6] = {4, 7, 10, 3, 8, 1};
    int even = 0, odd = 0;
    for (int i = 0; i < 6; i++) {
        if (a[i] % 2 == 0) even++;
        else odd++;
    }
    cout << "even " << even << ", odd " << odd << endl;
    return 0;
}

二维数组是「行的行」

#include <iostream>
using namespace std;

int main() {
    int g[3][2] = {{1, 2}, {3, 4}, {5, 6}};

    for (int r = 0; r < 3; r++) {
        for (int c = 0; c < 2; c++) {
            cout << g[r][c] << " ";
        }
        cout << endl;
    }
    return 0;
}

第一个下标永远是行。写反了会悄悄把你的数据转置 —— 矩阵转置 练的就是这个坑。

不会自我宣告的 bug

练习:数组最大值、奇偶统计、矩阵求和。下一步:Big O 表示法 解释为什么对这个数组套双重循环是 O(n²)。