📌 指针基础
所属等级: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 没有指向任何变量(野指针),就直接解引用,行为是未定义的,可能崩溃。指针必须先指向一个真实变量再使用。
🛡️ 避坑总结
&取地址,*解引用,声明指针用int* p;- 数组名即首地址,
*(p+i)等价于arr[i]; - 指针算术按类型大小跳跃,
p+1走到下一元素; - 函数要修改外部变量,就传
&变量用指针形参; - 绝不解引用未初始化的野指针,避免越界。
💡 提示:按 ← → 方向键可在上一 / 下一知识点间快速翻页