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

指针=专门用来存"地址"的变量。变量是一个盒子,盒子有门牌号;前面六章你只关心盒子里装什么,从这一节起开始关心"盒子在哪儿"。指针就是一张记着门牌号的小纸条——拿着它,就能直接找到那户人家、甚至改人家的东西。

📝 本节和前面几节的关系

7.1~7.3 你已经在用"地址"这个概念了,只是没点破:数组"连续存放"说的是地址挨着、sizeof 量的是"占地多少"、strcat 越界写坏内存说的就是"写到了别人的地址上"。指针把这一切摊到明面上。它也是 6.3.1 那个"swap 换不动"的伏笔的回收起点——想改原件,就得把地址交出去。

一、变量的两样东西:值和地址

int a = 10;

这一个盒子里装着 10,而盒子本身住在内存的某个门牌号上:

        a
     ┌──────┐
     │  10  │      ← 盒子里装的"值"
     └──────┘
      0x7ffd   ← 盒子自己的"地址"(门牌号)
概念 怎么拿到 说明
值 直接写 a 前面六章你一直只用它
地址 写 &a & 是"取地址运算符"

地址长什么样:一串十六进制数(如 0x7ffd4a2c),每次运行都可能不同——它就是"这块内存在哪"的编号。

二、为什么需要指针(三个理由)

理由 说明 在哪回收
改原件 想改一个变量的值,把它的地址交出去就行 7.6.1 的"传递地址"、6.3.1 的 swap 伏笔
高效处理数组 数组在内存里本就连续,用指针"走一遍"比反复算下标更快、更自然 7.5.1~7.5.3
理解底层 字符串、new 出来的对象、函数指针……全都建立在指针上 本课后续 + 第 8 章起

一句提醒:指针是 C++ 里最"危险"也最"有力"的东西。它能随心所欲改内存(所以强),也能一不小心改错内存(所以险)。7.4.4 的空指针、7.4.5 的常量指针,都是给你配的安全带。

三、本节五篇分工

小节 要解决的问题
7.4.1 变量与指针 指针变量长什么样、怎么声明
7.4.2 指针运算符和取地址运算符 & 和 * 到底各干什么(本节最核心)
7.4.3 指针运算 指针能加减吗?"加 1"加的是什么
7.4.4 指向空的指针与空类型指针 NULL 与 void *——两根重要的安全带
7.4.5 指向常量的指针与指针常量 const 和 * 谁管谁

四、动手 Demo:先看一眼地址

#include <iostream>
using namespace std;

int main() {
    int  a = 10;
    int  b = 10;
    char c = 'A';

    cout << "a 的值   = " << a  << endl;
    cout << "a 的地址 = " << &a << endl;
    cout << "b 的地址 = " << &b << endl;
    cout << "c 的地址 = " << &c << endl;

    cout << "sizeof(a)   = " << sizeof(a)   << endl;
    cout << "sizeof(&a)  = " << sizeof(&a)  << endl;
    return 0;
}

看到什么算成功:a 的值 = 10;三个地址都是 0x 开头的十六进制数(比如 0x61ff0c),每次运行都可能不一样;最后两行是 4 和 4(或 8)——地址本身也要占空间。

读结果的两个要点:

30 秒实验:把 int b = 10; 改成 int b = 20;,重跑——a、b 的值都变了,但它们的地址一模一样。这说明:地址是"位置",值是"内容",改内容不动位置。

五、常见误区

  1. "指针就是地址"——不严谨。指针是一个变量(有自己的一块空间),它里面存的是一个地址。说"指针是地址"就像说"信封是收件人"。
  2. "地址会变,所以没法用"——地址每次运行可能不同,但程序里从来不需要写死地址:你总是通过 &变量 拿地址、通过 *指针 用地址。
  3. "指针太难,能不能跳过"——本章后半(7.5~7.8)全建立在它上面,跳不过去。但好消息是:核心只有两个符号(& 和 *),下一节就把它讲透。
自测三问(点开对答案) 1. 指针里装的是什么?——**一个地址**(内存门牌号),不是普通的值。 2. 怎么拿到变量 `a` 的地址?——`&a`。 3. 为什么 `sizeof(&a)` 和 `sizeof(a)` 可能不一样?——`sizeof(a)` 是变量类型的大小(如 4),`sizeof(&a)` 是**指针本身**的大小(32 位系统 4、64 位系统 8)。

相关笔记