C 语言指针详解
发表时间:2026-06-19 | 分类:C 语言基础
什么是指针
指针是 C 语言中最强大也最容易出错的概念之一。简单来说,指针就是存储内存地址的变量。在 32 位系统中,指针占用 4 个字节;在 64 位系统中,指针占用 8 个字节。
int a = 10; // 普通变量,存储值 10
int *p = &a; // 指针变量,存储 a 的地址
// a 的值:10
// &a 的地址:0x7fff5694dc58
// p 的值:0x7fff5694dc58(就是 a 的地址)
// *p 的值:10(解引用,取出指向的值)
指针与数组
数组名本质上是一个指向数组首元素的指针常量。以下两种访问方式是等价的:
int arr[] = {1, 2, 3, 4, 5};
int *p = arr; // p 指向 arr[0]
arr[2] 等价于 *(arr + 2) // 都是 3
p[2] 等价于 *(p + 2) // 都是 3
注意:数组名是常量,不能做
arr++;但指针是变量,可以 p++ 遍历数组。
多级指针
指向指针的指针,称为二级指针。以此类推可以有更多层级,但实际开发中超过三级指针会严重影响可读性。
int a = 10;
int *p = &a; // 指向 int
int **pp = &p; // 指向 int*
// *pp 得到 p(即 a 的地址)
// **pp 得到 10(即 a 的值)
函数指针
函数指针可以让你把函数当作参数传递,是 C 语言实现回调机制的基础。
// 声明一个函数指针类型:指向 int(int, int) 的函数
int (*func_ptr)(int, int);
int add(int a, int b) { return a + b; }
func_ptr = add; // 赋值
int result = func_ptr(3, 4); // 调用,result = 7
野指针与空指针
野指针
指向已释放内存或未知区域的指针。使用野指针会导致未定义行为,是 C 程序崩溃的常见原因。
int *p; // 未初始化,是野指针
*p = 10; // 危险!不知道写到哪里了
int *q = malloc(sizeof(int));
free(q);
*q = 20; // 危险!访问已释放的内存
最佳实践:指针声明时立即初始化为
NULL;释放内存后立即将指针置为 NULL。
空指针
NULL 是一个宏,表示指针不指向任何有效地址。解引用 NULL 指针会导致段错误(Segmentation Fault)。
int *p = NULL;
if (p != NULL) {
*p = 10; // 安全检查
}
指针运算
指针的加减运算是以指向类型的字节数为单位进行的:
int arr[] = {10, 20, 30};
int *p = arr;
p + 1 // 不是地址 + 1,而是地址 + sizeof(int)
// 在 32 位系统中是地址 + 4
*(p + 1) // 等价于 arr[1],值为 20
总结
- 指针存储地址,用
*解引用 - 数组名是指针常量,指向首元素
- 函数指针让代码更灵活,但别滥用
- 释放内存后把指针置为
NULL - 指针运算以类型大小为单位,不是按字节