1. 从内存布局理解指针的本质
在C语言中,指针之所以让初学者感到困惑,很大程度上是因为没有建立起清晰的内存模型。让我们先抛开函数指针和指针函数这些概念,从最基础的内存访问机制说起。
每个变量在内存中都占据一块连续的空间,比如一个int类型变量通常占用4字节。当我们声明int a = 10;时,编译器会做两件事:
- 在内存的某个位置(假设地址为0x1000)分配4字节空间
- 在这4字节中存储数值10的二进制表示
此时,&a这个操作就是获取变量a的内存地址(0x1000),而*操作符则是通过地址访问该内存位置的值。这就是指针最基础的功能——内存地址的存储和间接访问。
关键理解:指针变量本身也是一个变量,它存储的值是内存地址。在32位系统中指针占4字节,64位系统中占8字节,这与它指向的数据类型无关。
2. 指针函数:返回指针的函数
2.1 基本定义与使用场景
指针函数这个名称其实不太准确,更专业的说法是"返回指针的函数"。它的声明形式如下:
c复制int *func(int a, float b);
这表示func是一个函数,它接受int和float参数,返回一个指向int的指针。
这种函数在以下场景特别有用:
- 动态内存分配(malloc家族函数就是典型的指针函数)
- 返回数组或字符串的首地址
- 返回静态变量或全局变量的地址
2.2 典型应用:字符串处理函数
C标准库中的许多字符串函数都是指针函数的典型例子:
c复制char *strcpy(char *dest, const char *src);
char *strcat(char *dest, const char *src);
这些函数都返回目标字符串的指针,支持链式调用:
c复制char buffer[100];
strcat(strcpy(buffer, "Hello"), " World!");
2.3 常见陷阱与规避方法
使用指针函数时最容易犯的错误是返回局部变量的地址:
c复制int *dangerous_func() {
int local = 42;
return &local; // 严重错误!
}
当函数返回后,局部变量local的
