指针总结
1. 指针是什么?
指针是地址,即内存单元的编号。它是一种数据类型,专门用来处理“地址”这种数据。
指针与普通变量的区别
| 特性 | 普通变量 | 指针变量 |
|---|
| 存储内容 | 数据值 | 内存地址 |
| 用途 | 存储数据 | 存储地址,用于间接访问数据 |
定义指针变量
int *p; // 定义一个指向 int 类型的指针变量 p
int:基类型,表示指针所指向的数据类型。*:定义指针时的符号,表示该变量是一个指针。p:指针变量名。
指针的大小
2. 指针的使用
获取变量的地址
int a = 10; int *p = &a; // p 存储了 a 的地址
解引用操作(*)
*p = 20; // 修改 a 的值为 20
指针运算
| 运算 | 说明 |
|---|
p + 1 | 地址增加一个基类型大小 |
p - 1 | 地址减少一个基类型大小 |
p - q | 计算两个指针之间的差值(需同类型) |
p > q | 比较地址大小 |
3. 指针与数组
数组与指针的关系
- 数组名代表首元素的地址,即
a == &a[0]。 - 通过指针可以访问数组元素:
int a[5] = {1, 2, 3, 4, 5}; int *p = a; printf("%d
", *(p + 2)); // 输出 3
### 一维数组 - 通过指针遍历数组: ```c for (int i = 0; i < 5; i++) { printf("%d ", a[i]); }
二维数组
", p[1][2]); // 等价于 a[1][2]
--- ## 4. 指针与函数参数 ### 值传递 vs 地址传递 | 传递方式 | 是否能修改主调变量 | 说明 | |----------|--------------------|------| | 值传递 | 否 | 传递的是变量的副本 | | 地址传递 | 是 | 传递的是变量的地址,可修改主调变量 | ### 示例:通过指针修改主调变量 ```c void addOne(int *p) { *p = *p + 1; } int main() { int n = 10; addOne(&n); // 通过地址传递,修改 n 的值 printf("n = %d ", n); // 输出 11 return 0; }
5. 指针的高级应用
指针数组
数组指针
多重指针 指针的指针(二级指针):
int a = 10; int *p = &a; int **pp = &p; // pp 是指向指针 p 的指针 printf("%d ", **pp); // 输出 10
6. 指针的常见问题
| 问题 | 说明 |
|---|
| 空指针 | 指针未初始化或指向无效地址,可能导致程序崩溃 |
| 指针越界 | 操作超出数组范围,导致未定义行为 |
| 内存泄漏 | 动态分配的内存未释放,导致资源浪费 |
7. 指针的应用场景
| 应用场景 | 说明 |
|---|
| 动态内存分配 | 使用malloc、calloc等函数分配和释放内存 |
| 字符串处理 | 通过指针操作字符串,如strcpy、strlen等 |
| 函数参数传递 | 通过地址传递实现被调函数对主调函数变量的修改 |
| 数据结构 | 表示复杂的数据结构,如链表、树、图等 |
8. 指针的优缺点
| 优点 | 缺点 |
|---|
| 高效访问内存 | 使用不当容易出错 |
| 支持动态内存管理 | 学习难度较高 |
| 可以直接操作硬件 | 指针越界、空指针等问题难以调试 |
9. 指针的总结
| 项目 | 内容 |
|---|
| 指针本质 | 地址,用于间接访问内存 |
| 指针类型 | 根据所指向的数据类型定义 |
| 指针运算 | 支持加减、比较等操作 |
| 指针与数组 | 数组名是首元素地址,指针可用于遍历数组 |
| 指针与函数 | 通过地址传递实现被调函数对主调函数变量的修改 |
| 指针的高级应用 | 指针数组、数组指针、多重指针等 |
指针是 C 语言的核心特性之一,掌握指针是学习 C 语言的关键。
参考来源
- C语言数组之指针数组和数组指针
- C语言中指针和数组详解
- C语言指针数组和数组指针详解
- C语言指针操作(三)通过指针引用数组
- C语言指针操作(九)指针数组和多重指针