C 语言指针:指针变量与地址操作
C 语言指针的核心在于理解“内存地址”与“数据值”的关系。掌握指针变量和地址操作,能够直接对内存进行读写,是编写高效 C 程序的基础。
理解内存地址与变量
计算机内存被划分为一个个连续的存储单元,每个单元都有一个唯一的编号,这个编号就是内存地址。在程序中定义的变量,本质上就是向系统申请了一块内存区域来存储数据。
-
定义 一个整型变量并初始化。
在代码中写入:int num = 10;此时,系统在内存中分配了空间(例如 4 个字节),并将
10填入其中。假设这块内存的起始地址是0x7ffee4。 -
获取 变量的内存地址。
使用取地址运算符&查看num的地址。printf("num 的地址: %p\n", &num);&num表示“变量num的地址”。%p是专门用于打印地址的格式控制符。
声明与初始化指针变量
指针变量是一种专门用来存储内存地址的变量。
-
声明 一个指针变量。
指针声明时需要指定它指向的数据类型,这样系统才知道读取内存时要读取多少个字节。int *p; // 声明一个指向整型的指针 p这里的
*只是告诉编译器p是一个指针,此时p内部还没有存储有效的地址。 -
初始化 指针变量。
将变量num的地址赋值 给指针p。p = #现在,
p的值就是0x7ffee4(即num的地址)。我们称“p指向了num”。 -
验证 指针的值。
运行 以下代码观察输出:printf("p 的值 (num 的地址): %p\n", p); printf("num 的地址: %p\n", &num);两者输出的结果完全一致。
为了更直观地理解这种指向关系,请参考下面的内存模型图:
使用指针访问与修改数据
指针最强大的功能在于通过地址间接操作它指向的数据。
-
使用 解引用运算符
*获取数据。
在指针变量前使用*,表示访问该地址处存储的数据。int value = *p; // 读取 p 指向地址的值 printf("*p 的值: %d\n", value); // 输出 10 -
通过 指针修改 原变量的值。
执行 赋值操作:*p = 20; printf("num 的值: %d\n", num); // 输出 20虽然代码中只操作了
p,但因为p指向num,所以num的值也变成了20。
指针的运算与数组
在 C 语言中,数组名本身就是一个地址(指向数组第一个元素的地址)。指针可以像数组下标一样遍历数据。
-
定义 数组并将指针指向数组首地址。
int arr[3] = {100, 200, 300}; int *ptr = arr; // 等同于 int *ptr = &arr[0]; -
通过 指针偏移访问 数组元素。
对指针进行加法运算(如ptr + 1)并不是简单的数值加 1,而是指向数组的下一个元素。地址的增加量取决于指针指向的数据类型(int类型通常增加 4 个字节)。计算地址偏移的公式为:
$$ \text{新地址} = \text{当前地址} + (\text{偏移量} \times \text{sizeof}(类型)) $$运行 以下代码查看效果:
printf("第一个元素: %d\n", *ptr); // 输出 100 printf("第二个元素: %d\n", *(ptr + 1)); // 输出 200 printf("第三个元素: %d\n", *(ptr + 2)); // 输出 300 -
使用 循环和指针遍历 数组。
for (int i = 0; i < 3; i++) { printf("%d ", *(ptr + i)); }
指针作为函数参数
C 语言中函数参数传递默认是“值传递”(复制一份副本)。如果要在函数内部修改函数外部变量的值,必须传递变量的地址(指针)。
-
编写 一个交换函数。
如果直接传变量,无法交换外部实参的值。必须接收指针:void swap(int *x, int *y) { int temp = *x; // 取出地址 x 中的值 *x = *y; // 将 y 的值赋给 x 地址处的内存 *y = temp; // 将 temp 赋给 y 地址处的内存 } -
调用 函数时传递地址。
int a = 5, b = 9; printf("交换前: a=%d, b=%d\n", a, b); swap(&a, &b); // 传递 a 和 b 的地址 printf("交换后: a=%d, b=%d\n", a, b);
常见操作符速查表
| 符号 | 名称 | 作用 | 示例代码 | 含义 |
|---|---|---|---|---|
& |
取地址符 | 获取变量在内存中的地址 | int a = 10; int *p = &a; |
将 a 的地址赋给 p |
* |
解引用符 | 访问指针地址所存储的数据 | int b = *p; |
读取 p 指向的值赋给 b |
* |
声明符 | 声明一个指针变量 | int *p; |
定义一个名为 p 的整型指针 |
指针安全注意事项
在操作指针时,必须遵守以下规则以防止程序崩溃。
-
避免 野指针。
指针在声明后若未初始化,其内部可能包含一个随机的垃圾地址。直接访问该地址会导致未定义行为或程序崩溃。
修正 方法:声明时初始化 为NULL。int *p = NULL; // 初始化为空 -
检查 指针是否为空。
在使用指针前,务必判断它是否指向了有效内存。if (p != NULL) { *p = 10; // 安全操作 } -
防止 指针越界。
当使用指针遍历数组时,确保指针移动范围不超过数组的边界。

暂无评论,快来抢沙发吧!