🔷 第七章 数组、指针和引用
📄 一句话概括

数组初始化就是声明的时候顺手把一排柜子一次摆好,用花括号:int a[5] = {1, 2, 3, 4, 5};。三种常见形态——全填、填几个(其余自动补 0)、一个不填({} 全刷 0)。记住那个实用技巧:int a[5] = {}; 是一句把整排刷成 0 的最短写法。

📝 本节和前面几节的关系

7.1.1 讲声明(订柜子,里面是垃圾值)、7.1.2 讲访问(开柜门)。这一节补上最关键的一环:怎么让格子一开始就是干净的。它还回收了 2.3.2 的老账——"未初始化=垃圾值"在数组里放大成了一整排垃圾。花括号的用法和 2.2.4 的数组成员初始化是同一套语法。

一、三种常见写法

写法 1:全部填满

int a[5] = {1, 2, 3, 4, 5};

格子数和花括号里的个数对得上,最省心。看到这行,a[0]=1、a[4]=5 一目了然。

写法 2:填一部分,其余自动补 0

int b[5] = {1, 2};         // b = {1, 2, 0, 0, 0}

前面的按你写的填,后面没写的一律补 0。这是很实用的一条:想"前三个有值、后面留空",直接写三个就行,不用把 0 也敲出来。

写法 3:一个都不填 → 全部刷 0

int c[5] = {};             // c = {0, 0, 0, 0, 0}

花括号里空空如也,但效果是"全部置 0",不是"什么都不做"。这一句是本书里把整排数组清零最短的写法,比循环赋值还短:

// 笨办法
for (int i = 0; i < 5; i++) c[i] = 0;

// 聪明办法
int c[5] = {};

顺带:长度可以省略

int d[] = {7, 8, 9};       // 长度自动算成 3

方括号留空、由初始化列表数出长度。适合那种"值是固定的、懒得去数几个"的场景。注意:要么省长度、要么省不了——下面这两种省法不成立:

int e[5];                  // ❌ 声明可以,但这不是初始化
e = {1, 2, 3, 4, 5};       // ❌ 数组不能整体赋值!

第二条是本节的重量级坑:数组不能在声明之后用花括号整体赋值。初始化只能跟在声明那一刻。

二、对照表:前三种写法到底填了什么

写法 a[0] a[1] a[2] a[3] a[4]
int a[5] = {1,2,3,4,5}; 1 2 3 4 5
int a[5] = {1,2}; 1 2 0 0 0
int a[5] = {5}; 5 0 0 0 0
int a[5] = {}; 0 0 0 0 0
int a[5];(不初始化) 垃圾 垃圾 垃圾 垃圾 垃圾

特别注意第三行:={5} 只把第一格设成 5,其余补 0——它不是在给每一格填 5。想全填 5 得写 {5,5,5,5,5} 或者用循环。这个坑特别深,因为看起来很像"把 5 填进去"。

三、动手 Demo:四种形态对照打印

#include <iostream>
using namespace std;

void printArr(int a[], int n) {            // 数组作参数的写法,7.8.3 详解
    for (int i = 0; i < n; i++) cout << a[i] << " ";
    cout << endl;
}

int main() {
    int full[5]  = {1, 2, 3, 4, 5};
    int part[5]  = {1, 2};
    int single[5] = {5};
    int zero[5]  = {};

    cout << "全填  :"; printArr(full, 5);
    cout << "填两个:"; printArr(part, 5);
    cout << "填一个:"; printArr(single, 5);
    cout << "花括号:"; printArr(zero, 5);
    return 0;
}

看到什么算成功:

全填  :1 2 3 4 5
填两个:1 2 0 0 0
填一个:5 0 0 0 0
花括号:0 0 0 0 0

逐行读:{1,2} 后面自动补 0;{5} 只有第一格是 5,后面全是 0(这就是上面表格第三行的现场证据);{} 整排 0。

30 秒实验:新增一行 int junk[5]; 并用 printArr(junk, 5) 打印,重跑——你会看到 5 个没有规律的数字。把 int junk[5]; 改成 int junk[5] = {}; 再跑,立刻变成 5 个 0。一句话之差,垃圾值变干净值。

四、常见误区

  1. "int a[5] = {5}; 是把 5 填满 5 格"——不是。只有 a[0] = 5,其余补 0。想全填 5 要写 {5,5,5,5,5} 或循环。
  2. "不写花括号也能用,反正差不太多"——差得远。不初始化=一整排垃圾值(2.3.2),任何判断和累加都会跟着乱。
  3. "int a[] ; 可以让长度自动出来"——不行。省略长度必须配合初始化列表:int a[] = {1,2,3}; 才是"长度自动算"。
  4. "声明后还能 a = {1,2,3};"——不行。花括号整体赋值只能在声明那一刻。声明之后只能一格一格赋值。
  5. "初始化列表给多了会自动截断"——给多了直接编译报错(too many initializers),这是编译器难得帮你把关的地方。
自测三问(点开对答案) 1. `int a[4] = {9};` 之后 `a[2]` 是几?——`0`。只填了第一格,其余自动补 0。 2. 怎么用最短的写法把整排数组刷成 0?——`int a[n] = {};` 3. 声明完还能 `a = {1,2,3};` 吗?——不能。数组不能整体赋值,只能一格一格来。

相关笔记