一、先搞懂内存:指针的底层基础
要理解指针,首先要明白内存的工作方式:
- 内存是由一个个存储单元组成的,每个单元都有唯一的地址(比如
0x1000) - 每个地址中存储着具体的值(比如
0x4) - 变量的本质就是“地址+值”的组合,编译器会帮我们管理地址,我们只需要通过变量名操作值
// 定义一个普通变量
int x = 4;
这段代码的含义是:在内存中分配一个int类型的存储单元,地址由编译器决定(比如0x1000),并将值4存入该地址。
二、指针是什么?存储地址的变量
指针本质是一个存储内存地址的变量。如果普通变量是“装值的盒子”,那么指针就是“装盒子地址的便签”。
1. 指针的定义与赋值
int x = 4; // 普通变量x,地址假设为0x1000,值为4
int *pX = &x; // 指针pX,存储x的地址(0x1000)
int *pX:定义一个指向int类型的指针变量pX&x:取地址符,获取变量x的内存地址pX的值就是x的地址(0x1000)
2. 解引用:通过指针访问值
通过指针的“解引用”操作,可以直接访问指针指向地址中的值:
int y = *pX; // 解引用pX,获取x的值(4),赋值给y
*pX:解引用符,读取pX存储的地址中的值- 此时
y的值就是4,和直接赋值y = x效果相同
三、指针的核心作用:避免值拷贝,直接操作内存
指针最核心的价值是直接操作内存,避免函数参数的“值拷贝”,从而实现对原变量的修改。
1. 错误示例:值拷贝无法修改原变量
如果函数参数是普通变量,传入的是变量的拷贝,函数内部修改的是拷贝的值,不会影响原变量:
#include <stdio.h>
// 错误:传入的是Player的拷贝,无法修改原对象
typedef struct {
int hp;
} Player;
void player_hurt(Player player) {
player.hp -= 10; // 修改的是拷贝的hp,原对象不受影响
}
int main() {
Player hurt_player = {100};
player_hurt(hurt_player);
printf("玩家血量:%d\n", hurt_player.hp); // 输出100,没有变化
return 0;
}
2. 正确示例:用指针直接修改原变量
如果函数参数是指针,传入的是原变量的地址,函数内部可以直接修改原变量的值:
#include <stdio.h>
typedef struct {
int hp;
} Player;
// 正确:传入Player的指针,直接修改原对象
void player_hurt(Player *player) {
player->hp -= 10; // 通过指针修改原对象的hp
}
int main() {
Player hurt_player = {100};
player_hurt(&hurt_player); // 传入原对象的地址
printf("玩家血量:%d\n", hurt_player.hp); // 输出90,修改成功
return 0;
}
四、指针的常见用法与注意事项
1. 指针与数组
数组名本质是一个指向数组首元素的指针:
int arr[5] = {1, 2, 3, 4, 5};
int *pArr = arr; // 等价于int *pArr = &arr[0];
printf("%d\n", *pArr); // 输出1,访问首元素
printf("%d\n", *(pArr+1)); // 输出2,访问第二个元素
2. 空指针与野指针
- 空指针:指向
NULL的指针,不指向任何有效内存地址int *p = NULL; // 安全的空指针,避免野指针 - 野指针:未初始化或指向已释放内存的指针,会导致程序崩溃
int *p; // 未初始化,野指针 *p = 10; // 错误,会导致程序崩溃
3. 指针的指针(二级指针)
二级指针是存储一级指针地址的变量,常用于函数中修改一级指针的值:
void alloc_memory(int **p) {
*p = (int *)malloc(sizeof(int)); // 修改一级指针的指向
}
int main() {
int *p = NULL;
alloc_memory(&p); // 传入一级指针的地址
*p = 10;
printf("%d\n", *p); // 输出10
free(p);
return 0;
}
五、总结:指针的本质是“内存地址的名片”
指针的核心逻辑可以总结为三句话:
- 指针是变量:存储的是内存地址
- 解引用是访问:通过指针可以直接操作内存中的值
- 指针的价值是高效:避免值拷贝,直接修改原变量,节省内存和时间
在嵌入式开发中,指针是操作硬件寄存器、处理大数据、实现高效函数调用的必备工具。掌握指针,你才能真正理解C语言的“底层控制力”。
9403

被折叠的 条评论
为什么被折叠?



