文章目录
- [1. 指向指针的指针(int pp)](#1. 指向指针的指针(int pp))
-
- [1.1 基本概念](#1.1 基本概念)
- [1.2 内存模型](#1.2 内存模型)
- [1.3 实战应用](#1.3 实战应用)
- [2. 函数指针](#2. 函数指针)
-
- [2.1 什么是函数指针?](#2.1 什么是函数指针?)
- [2.2 声明与使用](#2.2 声明与使用)
- [2.3 高级应用](#2.3 高级应用)
- [3. 结构体指针](#3. 结构体指针)
-
- [3.1 基本用法](#3.1 基本用法)
- [3.2 动态内存分配](#3.2 动态内存分配)
- [3.3 链表实现](#3.3 链表实现)
- [4. 综合实战](#4. 综合实战)
- [5. 避坑指南](#5. 避坑指南)
1. 指向指针的指针(int pp)
1.1 基本概念
- 指向指针的指针(多级指针)是指存储指针变量地址的指针,常用于动态多维数组、链式数据结构等场景。
c
int a = 10;
int *p = &a; // p 存储 a 的地址
int **pp = &p; // pp 存储 p 的地址
1.2 内存模型
c
a = 10 (地址: 0x1000)
p = 0x1000 (地址: 0x2000)
pp = 0x2000 (地址: 0x3000)
1.3 实战应用
- 动态二维数组
c
int rows = 3, cols = 4;
int **matrix = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
matrix[i] = (int *)malloc(cols * sizeof(int));
}
- // 使用 matrix[i][j]
- // 释放内存略
- 修改指针变量
c
void changePointer(int **pp) {
int b = 20;
*pp = &b; // 修改外部指针的指向
}
int main() {
int a = 10;
int *p = &a;
changePointer(&p); // p 现在指向 b
return 0;
}
2. 函数指针
2.1 什么是函数指针?
函数指针是指向函数入口地址的指针,可用于实现回调机制、动态函数调用等。
2.2 声明与使用
c
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int main() {
// 声明函数指针
int (*op)(int, int);
op = add; // 指向 add 函数
printf("%d\n", op(2, 3)); // 输出 5
op = sub; // 切换指向 sub 函数
printf("%d\n", op(5, 2)); // 输出 3
return 0;
}
2.3 高级应用
- 回调函数(Callback)
c
void process(int x, int y, int (*callback)(int, int)) {
printf("Result: %d\n", callback(x, y));
}
int main() {
process(10, 5, add); // 输出 15
process(10, 5, sub); // 输出 5
return 0;
}
- 函数指针数组
c
int (*ops[2])(int, int) = {add, sub};
printf("%d\n", ops[0](3, 2)); // 调用 add
printf("%d\n", ops[1](3, 2)); // 调用 sub
3. 结构体指针
3.1 基本用法
结构体指针用于高效操作复杂数据结构,避免值传递的内存拷贝
c
typedef struct {
int id;
char name[20];
} Student;
int main() {
Student s = {1, "Alice"};
Student *p = &s;
printf("%s\n", p->name); // 使用 -> 访问成员
return 0;
}
3.2 动态内存分配
c
Student *createStudent(int id, const char *name) {
Student *s = (Student *)malloc(sizeof(Student));
s->id = id;
strcpy(s->name, name);
return s;
}
int main() {
Student *s = createStudent(2, "Bob");
printf("%d: %s\n", s->id, s->name);
free(s); // 释放内存
return 0;
}
3.3 链表实现
c
typedef struct Node {
int data;
struct Node *next;
} Node;
int main() {
Node *head = NULL;
// 插入节点
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->data = 10;
newNode->next = head;
head = newNode;
// 遍历链表略
return 0;
}
4. 综合实战
案例:通用排序函数
c
// 比较函数
int cmpInt(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
void sort(void *arr, int n, int size, int (*cmp)(const void *, const void *)) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
void *p1 = (char *)arr + j * size; // 计算元素地址
void *p2 = (char *)arr + (j+1) * size;
if (cmp(p1, p2) > 0) {
swap(p1, p2, size); // 交换内存块
}
}
}
}
int main() {
int arr[] = {5, 2, 8, 1};
sort(arr, 4, sizeof(int), cmpInt);
// 输出排序结果略
return 0;
}
5. 避坑指南
问题类型 | 错误示例 | 修正方法 |
---|---|---|
多级指针解引用错误 | ***pp 无意义 | 明确层级:**pp 或 *pp |
函数指针类型不匹配 | int (*p)() 指向 void func() | 严格匹配返回值和参数类型 |
结构体指针未初始化 | Student *p; p->id=1; | 先分配内存或指向有效结构体变量 |
- 总结
- 指向指针的指针:用于动态多维数据结构、跨函数修改指针。
- 函数指针:实现回调、策略模式等灵活编程。
- 结构体指针:高效操作复杂数据,实现链表/树等动态结构。