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

总结