C语言指针进阶

文章目录

  • [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; 先分配内存或指向有效结构体变量
  1. 总结
  • 指向指针的指针:用于动态多维数据结构、跨函数修改指针。
  • 函数指针:实现回调、策略模式等灵活编程。
  • 结构体指针:高效操作复杂数据,实现链表/树等动态结构。
相关推荐
m0_640743562 小时前
华为OD-2024年E卷-字符串分割[100分] -- python
数据结构·算法·华为od
剪一朵云爱着6 小时前
力扣面试题 17.05. 字母与数字
算法·leetcode
code喵喵7 小时前
八种数据结构简介
数据结构·算法·推荐算法
C语言小火车7 小时前
【C语言】银行账户管理系统丨源码+解析
c语言·c++·算法·课程设计
wen__xvn7 小时前
九日集训第三天
数据结构·算法·leetcode
嵌引工坊8 小时前
Proteus如何创建第一个工程
c语言·单片机·嵌入式硬件·测试工具·proteus
dying_man8 小时前
LeetCode--33.搜索旋转排序数组
算法·leetcode
东方芷兰8 小时前
Leetcode 刷题记录 17 —— 堆
java·c++·b树·算法·leetcode·职场和发展
lzb_kkk8 小时前
【MFC】编辑框、下拉框、列表控件
c语言·开发语言·c++·mfc·1024程序员节
蒙奇D索大9 小时前
【数据结构】图论实战:DAG空间压缩术——42%存储优化实战解析
数据结构·笔记·学习·考研·图论·改行学it