C 语言指针完全指南:类型、用法与最佳实践
什么是 C 语言指针?
指针 是存储另一变量内存地址的变量。通过引用地址,指针可间接访问或修改所指数据。这种间接寻址实现高效内存使用与快速执行,尤其处理大型数据结构或动态内存分配时威力巨大。
如何使用指针
以整型变量 v 为例:
int v = 0;其值为 0,但每个变量也有唯一地址。用取地址运算符(
&)获取地址:printf("Address of v: %p\n", (void*)&v); 打印的地址为十六进制,每次运行可能不同。下面程序演示指针存储地址:
#include <stdio.h>
int main() {
int v = 0;
int *y = &v; // y 保存 v 的地址
printf("Address stored in y: %p\n", (void*)y);
printf("Value pointed to by y: %d\n", *y);
return 0;
}
典型输出:
Address stored in y: 0x7ffeefbff5c8 Value pointed to by y: 0
声明指针
指针声明模式:
data_type *pointer_name;
data_type 为指针指向的数据类型。合法示例:
int *ptr_int; // 指向 int double *ptr_double; // 指向 double char *ptr_char; // 指向 char
初始化指针
声明后必须用有效地址初始化。使用未初始化指针导致未定义行为。初始化语法:
pointer = &variable;示例:
#include <stdio.h>
int main() {
int a = 10;
int *p = &a;
printf("Address in p: %p\n", (void*)p);
printf("Value via p: %d\n", *p);
return 0;
}
C 语言指针类型
- 空指针 – 显式持有
NULL,表示无有效地址。适合初始化或哨兵值。int *p = NULL; // p 为空
- void 指针 – 通用指针类型(
void*),可持有任意类型地址。解引用前必须强转为具体类型。void *p = &intVar; // 通用地址
- 野指针 – 未初始化指针,指向任意内存位置。访问会导致段错误或不可预测行为。
int *p; // 未定义 printf("%d\n", *p); // 不安全 - 其他类型(悬空指针、函数指针、指针数组等)虽存在但日常代码较少用。
直接访问 vs 间接访问
直接访问用变量名;间接访问用指针。示例:
#include <stdio.h>
int var = 1;
int *ptr = &var;
printf("Direct: %d\n", var); // 1
printf("Indirect: %d\n", *ptr); // 1
*ptr = 48; // 通过指针修改
printf("After change, indirect: %d\n", *ptr); // 48
指针算术运算
指针指向数组元素时,加减整数按元素数移动而非字节。示例:
int arr[5] = {1,2,3,4,5};
int *p = arr; // 指向 arr[0]
for (int i = 0; i < 5; ++i) {
printf("%d\n", *p);
++p; // 移至下一元素
}
关键规则:
- 一元运算符
*和&优先级同其他一元运算符 - 表达式右向左求值
- 增加指向值用
++*p或(*p)++
指针与数组
指针提供简洁方式遍历数组元素:
int a[5] = {1,2,3,4,5};
int *p = a; // 等同 &a[0]
for (int i = 0; i < 5; ++i) {
printf("%d\n", *p++); // 打印 1 到 5
}
指针与字符串
字符串是以空字符结尾的 char 数组。指针操作让字符串遍历变得简单:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello Guru99!";
char *p = str;
printf("First character: %c\n", *p);
++p;
printf("Next character: %c\n", *p);
// 打印整个字符串
for (int i = 0; i < strlen(str); ++i) {
printf("%c\n", *p++);
}
return 0;
}
指针优势
- 直接内存访问与操作
- 高效遍历数组与链式数据结构
- 动态内存分配(
malloc、free)基础 - 支撑复杂结构:链表、树、图
潜在陷阱
- 未初始化(野)指针导致崩溃
- 解引用空指针或悬空指针引发段错误
- 分配内存未释放造成内存泄漏
- 指针误用破坏数据、调试困难
核心要点
- 指针存储内存地址,实现间接数据访问
- 正确声明、初始化、类型安全至关重要
- 空指针、void 指针、野指针代表不同用例
- 指针算术是数组与字符串操作的利器
- 精通指针解锁 C 语言高效底层编程的全部潜力
C语言