首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >灵光一现的问题和常见错误3

灵光一现的问题和常见错误3

作者头像
Ronin305
发布2025-12-22 12:59:40
发布2025-12-22 12:59:40
750
举报
文章被收录于专栏:我的博客我的博客

回顾复习一下来自《C语言与陷阱》的两段代码

代码语言:javascript
复制
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int)

代码1:(*(void (*)())0)();

这段代码的作用是调用内存地址为 0 的函数,本质是强制类型转换与函数指针的间接调用。具体解析如下:


1. 分步拆解
代码语言:javascript
复制
(*(void (*)())0)();
  1. (void (*)())0
    • 目的:将整数 0 强制转换为函数指针
    • 类型解释
      • void (*)() 表示一个指向函数的指针,该函数无参数返回 void
      • (void (*)())0 将内存地址 0 解释为这种函数指针。
  2. *(void (*)())0
    • 目的:解引用该函数指针,得到函数本身。
    • 等价于直接使用函数指针调用:((void (*)())0)()
  3. 最后的 ()
    • 作用:调用该函数。

2. 行为分析
  • 实际效果:尝试执行内存地址 0 处的代码。
  • 风险
    • 地址 0 是非法地址(通常为 NULL),调用会导致未定义行为(程序崩溃或系统异常)。
    • 常见于底层开发(如操作系统引导代码),但一般代码中禁止使用。

代码2:void (*signal(int, void(*)(int)))(int);

这是 UNIX/Linux 系统信号处理函数 signal 的标准声明,其功能是注册信号处理函数。解析如下:


1. 分步拆解
代码语言:javascript
复制
void (*signal(int, void(*)(int)))(int);
  1. signal 的参数
    • 第一个参数int 类型,表示信号编号(如 SIGINT)。
    • 第二个参数void(*)(int),指向一个接受 int 参数并返回 void 的函数(即信号处理函数)。
  2. signal 的返回值
    • void (*)(int),与第二个参数类型相同,表示旧的信号处理函数

2. 简化理解

功能signal 函数接受一个信号编号和一个新的处理函数,返回旧的处理函数。 例如:

代码语言:javascript
复制
void handler(int sig) { /* 处理信号 */ }
void (*old_handler)(int) = signal(SIGINT, handler);

等价 typedef 写法(增强可读性):

代码语言:javascript
复制
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t handler);

总结

代码

行为

应用场景

(*(void (*)())0)();

强制调用地址 0 的函数(危险操作,通常导致崩溃)

底层开发(极少使用)

void (*signal(int, void(*)(int)))(int);

注册信号处理函数,返回旧处理函数

UNIX/Linux 信号处理


补充说明

代码1 的替代写法

  • 更清晰的写法:((void (*)())0)();(直接通过函数指针调用,省略解引用)。
  • 二者等价,因为函数指针本身可以直接调用。

代码2 的工程实践

使用 typedef 简化复杂函数指针类型,提升代码可读性。

例如:

代码语言:javascript
复制
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t handler);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 回顾复习一下来自《C语言与陷阱》的两段代码
    • 代码1:(*(void (*)())0)();
      • 1. 分步拆解
      • 2. 行为分析
    • 代码2:void (*signal(int, void(*)(int)))(int);
      • 1. 分步拆解
      • 2. 简化理解
    • 总结
    • 补充说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档