1. 指针的本质与内存模型
指针是C语言中最强大也最危险的工具。理解指针的第一步是彻底搞明白它和内存的关系。在32位系统中,指针变量固定占4字节,64位系统中占8字节,这个大小与它指向的数据类型完全无关。指针变量里存储的只是一个内存地址,就像快递单号只记录包裹位置而不关心包裹内容一样。
我常对学生说:"指针就是内存的邮政编码"。当你声明int *p;时,系统只是预留了一个存放地址的盒子,这个盒子还没装任何有效的门牌号。此时如果直接解引用*p,就像按随机生成的地址去敲门,结果必然是段错误(segmentation fault)。
c复制int main() {
int *p; // 野指针
printf("%d", *p); // 崩溃!
return 0;
}
警告:未初始化的指针称为野指针(wild pointer),使用它是未定义行为。好的习惯是在声明时立即初始化为NULL。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 指针运算的底层逻辑
指针加减法的步长由基类型决定,这是理解数组遍历的关键。当执行p++时,实际地址增加值等于sizeof(基类型)。比如int *p的p++会使地址增加4字节(假设int为4字节),而double *p的p++会增加8字节。
c复制int arr[3] = {10, 20, 30};
int *p = arr; // 等价于 &arr[0]
printf("%d\n", *p); // 输出10
printf("%d\n", *(p+1)); // 输出20,地址实际加了4字节
printf("%d\n", p[1]); // 等价写法
这个特性使得指针可以高效遍历数组。在嵌入式开发中,我经常用指针操作硬件寄存器,比如:
c复制#define GPIO_BASE 0x40020000
volatile uint32_t *gpio = (uint32_t *)GPIO_BASE;
gpio[5] = 0x1; // 操作第6个寄存器
3. 多级指针的解引用艺术
二级指针(int **pp)常常让初学者困惑。其实可以这样理解:一级指针存储变量的地址,二级指针存储指针变量的地址。在动态二维数组和字符串数组
