🎁 当前为 免费试看 内容 · 开通VIP 解锁 GESP 通关手册全部 1–8 级知识点 + 题库 + 详细解析
🌐 主站
📖 已学 0

📌 指针基础

所属等级:GESP 4级 | 难度:★★★ | 关键词:&取地址、*解引用、指针与数组

📝 考纲要求

  • 理解内存地址与指针变量的概念,掌握取地址符 & 与解引用符 *;
  • 能用指针访问和修改普通变量的值;
  • 理解指针与数组的关系:数组名即首元素地址,可用指针遍历数组;
  • 了解指针作为函数参数时“传地址”的效果(为文件与算法打基础)。

📖 通俗讲解

💡 一句话理解 电脑内存像一排带门牌号的房间,变量是房间里放的东西,指针就是记着门牌号的纸条。用 & 查门牌号,用 * 顺着纸条进房间取东西。

取地址 &:给变量加 & 得到它的内存地址。
解引用 *:声明指针时用 int* p,使用 *p 表示“p 指向的那个变量”。

🖼️ 图解

内存像一排带门牌号的房间,指针 p 记着变量 a 的门牌号:
地址       内存格子            指针
0x1000   ┌─────────┐
         │  a = 10 │ ◄──── p  (= &a)
         └─────────┘
p 存的是地址 0x1000
*p 顺着地址取出里面的 10(解引用)
C++
#include <iostream>
using namespace std;
int main() {
    int a = 10;        // 普通变量 a,值为 10
    int* p = &a;      // p 是整型指针,存的是 a 的地址(& 取地址)
    cout << a << endl;   // 输出 10:直接看 a
    cout << *p << endl;  // 输出 10:*p 解引用,顺着地址取出 a 的值
    *p = 20;           // 通过指针修改 a 的值
    cout << a << endl;   // 输出 20:a 被改动了
    return 0;
}
输出10 10 20

指针与数组:数组名 arr 本身就是首元素 arr[0] 的地址;arr + i 指向第 i 个元素,即 &arr[i]。

C++
#include <iostream>
using namespace std;
int main() {
    int arr[4] = {1, 2, 3, 4};
    int* p = arr;            // 等价于 int* p = &arr[0];
    for (int i = 0; i < 4; i++) {
        cout << *(p + i) << " ";  // *(p+i) 等价于 arr[i]
    }
    cout << endl;
    return 0;
}
输出1 2 3 4

🔵 核心必背重点

✅ 必背
  • &a 是“a 的地址”,int* p 声明一个指向 int 的指针;
  • *p 是“p 指向的变量”,既能读也能写;
  • 数组名就是首地址:arr 等价于 &arr[0];
  • *(p + i) 等价于 arr[i],指针可以当数组用;
  • 指针的加减按“元素大小”跳,p + 1 指向下一个 int。
🔑
记忆口诀:“& 查门牌,* 进房间;数组名就是 0 号房,p+i 走到第 i 间。”

🔴 考试拉分难点

⚠️ 难点
  • 指针与地址的区别:p 是地址本身,*p 是地址里存的值;
  • 指针算术:p + 1 移动的字节数 = 类型大小(int 为 4 字节),不是简单 +1;
  • 函数传地址:把 &a 传给形参指针,函数里改 *p 会影响外面的 a。

🟡 高频易错陷阱

🚫 扣分坑点
  • 野指针:指针没指向任何变量就解引用 *p,程序可能崩溃;务必先 p = &a;;
  • 把 & 和 * 用反:取地址用 &,取值用 *;
  • 混淆 p 与 *p:输出 p 看到的是地址数字,不是里面的值;
  • 数组越界:*(p + 4) 已超出 4 个元素的范围,是非法访问。

🧪 例题演练

例题 1(基础题):用指针交换两个数

题目:输入两个整数,用指针作为函数参数交换它们,再输出。

C++
#include <iostream>
using namespace std;

// 交换函数:形参是指针,接收变量的地址
void swap(int* x, int* y) {
    int t = *x;   // 取出 x 指向的值,存到临时变量 t
    *x = *y;      // 把 y 指向的值赋给 x 指向的变量
    *y = t;       // 把原来的 x 值赋给 y 指向的变量
}

int main() {
    int a, b;
    cin >> a >> b;
    swap(&a, &b);  // 传地址,函数内改动会影响外面的 a、b
    cout << a << " " << b << endl;
    return 0;
}
输入 / 输出3 5 5 3

例题 2(模拟真题):指针遍历求数组和

题目:输入 n 个整数,用指针遍历数组求和并输出。

C++
#include <iostream>
using namespace std;
int main() {
    int n;
    cin >> n;
    int arr[110];          // 开足够大的数组
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    int* p = arr;          // p 指向首元素
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum = sum + *(p + i);  // 用指针取第 i 个元素,累加
    }
    cout << sum << endl;
    return 0;
}
输入 / 输出4 1 2 3 4 10
🚫 错误示范 int* p; cout << *p; —— p 没有指向任何变量(野指针),就直接解引用,行为是未定义的,可能崩溃。指针必须先指向一个真实变量再使用。

🛡️ 避坑总结

  1. & 取地址,* 解引用,声明指针用 int* p;
  2. 数组名即首地址,*(p+i) 等价于 arr[i];
  3. 指针算术按类型大小跳跃,p+1 走到下一元素;
  4. 函数要修改外部变量,就传 &变量 用指针形参;
  5. 绝不解引用未初始化的野指针,避免越界。

💡 提示:按 ← → 方向键可在上一 / 下一知识点间快速翻页

GESP 4级 · 学习进度 0/0

📑 本页目录