1. 指针的本质:内存世界的门牌号系统
指针是C语言中最强大也最令人困惑的特性之一。想象一下你生活在一个巨大的公寓楼里,每个住户都有一个唯一的门牌号。指针就是这个门牌号系统,它不直接存储数据本身,而是存储数据在内存中的"居住地址"。
在32位系统中,指针通常是4字节大小;在64位系统中则是8字节。这个大小固定不变,因为它只需要存储一个内存地址,而不关心这个地址指向的数据有多大。就像门牌号的大小不会因为住户房子的大小而变化一样。
注意:指针的大小与它指向的数据类型无关。一个int指针和一个char指针在相同系统中大小相同,只是它们"指向的楼房类型"不同。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 指针的声明与初始化:从理论到实践
2.1 指针声明语法解析
指针声明的语法看似简单却暗藏玄机:
c复制int *p; // 声明一个指向int的指针
这里的关键是理解*操作符的绑定关系。从技术上讲,*是与变量名结合而非类型名。也就是说,int* p和int *p是等价的写法,但后者更准确地反映了语法解析规则。
我个人更推荐int *p这种写法,因为它明确表示*p是一个int类型,而p本身是一个指针。这种写法在多重指针时尤其清晰:
c复制int **pp; // 指向int指针的指针
2.2 指针初始化的正确姿势
未初始化的指针就像一张写着随机地址的纸条,使用它可能导致程序崩溃。安全的做法是:
c复制int *p = NULL; // 显式初始化为空指针
或者直接让它指向一个有效变量:
c复制int num = 42;
int *p = # // &操作符获取变量的地址
实操心得:养成声明指针时立即初始化的习惯,哪怕初始化为NULL。这可以避免90%的野指针问题。
3. 指针的核心价值:直接内存操作
3.1 函数参数传递的革命
指针最强大的能力之一是允许函数修改调用者的变量。考虑这个常见的错误:
c复制void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
// 调用时
int x = 1, y = 2;
swap(x, y); // x和y的值不
