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. 总结
  • 指向指针的指针:用于动态多维数据结构、跨函数修改指针。
  • 函数指针:实现回调、策略模式等灵活编程。
  • 结构体指针:高效操作复杂数据,实现链表/树等动态结构。
相关推荐
路人与大师37 分钟前
用算法实现 用统计的方式实现 用自然语言处理的方法实现 用大模型实现 专利精益化统计分析
人工智能·算法·自然语言处理
五点钟科技38 分钟前
大语言模型的完整训练周期从0到1的体系化拆解
算法·自然语言处理
Dxy12393102161 小时前
Python经典算法实战
开发语言·python·算法
五步晦暝1 小时前
【排序算法】典型排序算法 Java实现
java·算法·排序算法
巨龙之路2 小时前
【TDengine源码阅读】taosMemoryDbgInit函数
大数据·linux·c语言·tdengine
摆烂仙君6 小时前
小米2025年校招笔试真题手撕(二)
算法
CodeWithMe8 小时前
【C/C++】线程状态以及转换
java·c语言·c++
xin007hoyo10 小时前
算法笔记·数学·最大公约数
笔记·算法