当前位置: 首页 > news >正文

【C语言】指针与回调机制学习笔记

1️⃣ 指针基础

  • 指针是变量,保存另一个变量的内存地址。
  • 定义格式:
int a = 10;
int *p = &a;  // p 是指向 int 类型变量 a 的指针
  • 重要符号说明:
表达式含义
p指针变量本身,保存地址值
*p解引用,访问指针指向地址上的内容
&a取地址符,获取变量 a 的内存地址
  • 例子:
int x = 5;
int *p = &x;
printf("x = %d\n", *p);  // 输出5

2️⃣ void * 指针(通用指针)

  • void * 是通用指针,可以指向任何类型数据。
  • 不能直接解引用,必须先强制类型转换。
  • 常用于函数参数泛化和动态内存分配。

示例:

void printInt(void *data) {int *p = (int *)data;printf("value: %d\n", *p);
}int a = 100;
printInt(&a);

3️⃣ 函数指针

  • 函数指针变量用于存储函数的地址。
  • 语法格式:
返回值类型 (*指针变量名)(参数类型列表)
  • 示例:
void greet(char *name) {printf("Hello, %s!\n", name);
}void (*fp)(char *) = greet;
fp("LBDX");

4️⃣ 函数注册与回调机制

4.1 函数指针类型定义

typedef void (*Callback)(void *);
  • typedef 定义一个类型别名 Callback
  • Callback 表示一个函数指针,指向接受一个 void * 参数且无返回值的函数。

4.2 注册函数定义

void registerTask(Task *task, Callback cb, void *arg)
  • registerTask 是注册任务的函数,无返回值。

  • 参数:

    • Task *task:指向任务结构体指针。
    • Callback cb:函数指针,注册的回调函数。
    • void *arg:传给回调函数的参数。

4.3 函数内部赋值

task->func = cb;   // 记录回调函数
task->arg = arg;   // 记录回调参数

4.4 完整示例

#include <stdio.h>typedef void (*Callback)(void *);typedef struct {Callback func;void *arg;
} Task;void registerTask(Task *task, Callback cb, void *arg) {task->func = cb;task->arg = arg;
}void runTask(Task *task) {if (task && task->func) {task->func(task->arg);}
}void sayHello(void *arg) {char *name = (char *)arg;printf("Hello, %s!\n", name);
}void showNumber(void *arg) {int *num = (int *)arg;printf("Received number: %d\n", *num);
}int main() {Task task1, task2;char name[] = "LBDX";int number = 42;registerTask(&task1, sayHello, name);registerTask(&task2, showNumber, &number);runTask(&task1);runTask(&task2);return 0;
}

输出:

Hello, LBDX!
Received number: 42

5️⃣ 重要总结

术语说明
*p解引用,访问指针指向地址的值
&x取地址,获取变量 x 的地址
void *通用指针,可指向任意类型,需强转
函数指针存储函数地址,可间接调用函数
typedef void (*Callback)(void *)定义函数指针类型,指向接受 void* 参数无返回值的函数
函数注册将函数指针和参数保存,用于后续调用(回调)
http://www.xdnf.cn/news/1085653.html

相关文章:

  • 【Java安全】反射基础
  • RoboRefer:面向机器人视觉-语言模型推理的空间参考
  • Web后端开发-分层解耦
  • Playfun即将开启大型Web3线上活动,打造沉浸式GameFi体验生态
  • 【ElasticSearch实用篇-01】需求分析和数据制造
  • turborepo 如何解决git管理包过大的问题
  • 病虫害数据集
  • 「Windows/Mac OS」AIGC图片生成视频 ,webui + stable-diffusion环境部署教程
  • AI编程才刚起步,对成熟的软件工程师并未带来质变
  • 【学习笔记】大数定理,频率与概率,均值与期望的区别
  • 深入解析TCP:可靠传输的核心机制与实现逻辑(三次握手、四次挥手、流量控制、滑动窗口、拥塞控制、慢启动、延时应答、面向字节流、粘包问题)
  • Java 命令行参数详解:系统属性、JVM 选项与应用配置
  • PCA通过“找最大方差方向”实现降维,本质是用更少的变量捕捉原始数据的主要模式
  • 3S技术+ArcGIS/ENVI全流程实战:水文、气象、灾害、生态、环境及卫生等领域应用
  • 深度学习7(梯度下降算法改进)
  • 使用Ideal创建一个spring boot的helloWorld项目
  • TMC4361A 使用(未验证)
  • 如何排查服务器中已经存在的后门程序?
  • 【应急响应】Linux 自用应急响应工具(LinuxCheckShoot)
  • 接口漏洞怎么抓?Fiddler 中文版 + Postman + Wireshark 实战指南
  • 提示工程(Prompt Engineering)研究进展
  • Camera相机人脸识别系列专题分析之十六:人脸特征检测FFD算法之libcvface_api.so数据结构详细注释解析
  • AWS VPC Peering
  • Linux中程序的limits中的Max open files的配置由哪些参数决定
  • 明星AI自动化测试工具Midscene.js源码解析
  • Pr插件图文安装教程
  • 实用机器学习
  • C盘瘦身 -- 虚拟内存文件 pagefile.sys
  • 华为OD机试 2025B卷 - 字符串加密 (C++ Python JAVA JS C语言)
  • Python实现文件夹中文件名与Excel中存在的文件名进行对比,并进行删除操作