【C陷阱与缺陷】两道“有趣”的代码题

news2025/1/15 20:33:02

在这里插入图片描述

在这里插入图片描述

如果读者不了解函数指针的,可以先看看这篇文章 链接

< 第一题 >

代码:

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

解析:

💬如果你是头一次看上面这段代码的话,心里一定是一个大大的问号???现在我就来解释一下

  • 本题的突破口在于这个0,仔细观察可以发现,0前面有一个括号(),括号里面的这种形式若是你自己去看的话就是一个函数指针,那相当于就是对0进行一个强制类型转换,把它变成一个函数地址,然后前面的*我们刚才讲过,就是对这个函数进行解引用,获取到这个函数。那么最后一步便是去调用这个函数

具体的分解可以看看下图👇

在这里插入图片描述
分步细说:

  1. void (*)() —— 》一个没有形参,返回类型为void的函数指针

  1. (void (*)())0 ——》 对0进行强制类型转换,使其被解释成为一个函数的地址

  1. *(void (*)())0 ——》对0地址处的函数进行解引用,获取到这个函数

  1. (*(void (*)())0)() ——》调用0地址处的函数

原文现身:
在这里插入图片描述

< 第二题 >

代码:

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

解析:

💬同理,若是第一次见一定会被它绕晕了😵了

  • 本题真的可以说是在套娃了,首先你看到的一定是signal,它呢是C语言中的一个信号函数,有兴趣可以去了解一下,我们知道()的优先级高于*,所以signal会和后面的内容先结合,那其实已经可以看出这是一个函数声明了。进到里面再来看看这个函数有两个参数,一个是int,一个是函数指针,那么外层的又是什么呢?
  • 仔细看下图,我将内部的signal()函数声明抽离了出来,只剩下了头和尾,你可以做一个视觉上的合并,那其实又是一个void (*)(int)的函数指针,其实这就是signal函数的返回类型,是一个函数指针

在这里插入图片描述

同样地,我们再来捋一遍

分步细说:

  1. void (*)(int) —— 》是一个函数指针,为signal函数的形参

  1. signal(int, void(*)(int)) ——》 是一个函数声明,signal与右侧的()率先结合,内部有两个形参

  1. void (*)(int) ——》也是一个函数指针,不过是作为signal函数返回类型

优化:

对于上面的这种写法你是否觉得很冗余,其实可以再度进行一个优化,那么你可能很快就看得懂了

  • 因为 void (*)(int) 是出现了两次,之前我们在C语言中有学习过typedef这个关键字,可以用来对一个很长的数据类型或者变量进行重命名,那么在这里我们也可以这样做
  • 不过呢,你要把重命名后的名字放在(*)里面,因为语法这么规定了,去掉变量名后就是它的类型
typedef void(*ptr_t)(int);
  • 于是这句代码就可以简化为下面这种形式👇注意解引用那个*不要了,函数指针这里是可以省略的
//void (*signal(int, void(*)(int)))(int);
ptr_t signal(int, ptr_t);

原文现身:

在这里插入图片描述


两道题讲完了,你是否有收获呢?有兴趣的话可以私信我,发你《C陷阱与缺陷》的电子书.pdf

—— 2023.4.8记

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435698.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++的输入输出概述

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C &#x1f525;座右铭&#xff1a;“不要等到什么都没有了&#xff0c;才下…

前缀和2:2615等值距离和

2615. 等值距离和 - 力扣&#xff08;LeetCode&#xff09; 做这道题之前&#xff0c;先完成1685. 有序数组中差绝对值之和 - 力扣&#xff08;LeetCode&#xff09; 一般性的&#xff0c;我们能在这类题目中总结出以下规律&#xff1a; 求解有序数组中每个元素与q的差值res时…

Traceroute的原理及应用挑战

1 Traceroute简介 Traceroute 是继 ping 之后使用最广泛的网络诊断工具之一&#xff0c;因为它简单且应用范围非常广泛。 traceroute 的可能应用范围从简单的网络错误诊断到揭示底层网络拓扑的大型扫描。然而&#xff0c;由于 traceroute 不是在考虑现代网络技术的情况下构建的…

让你轻松入门APP自动化测试:UiAutomator2框架基础解析

目录 前言 一、uiautomator/uiautomator2的前生今世 1.官方文档介绍 2.梳理一下脉络 3.三款框架对比 二、uiautomator2简介 1.项目组成 2.工作原理 三、环境搭建 1.安装uiautomator2 2.初始化设备 3.init时都干了啥&#xff1f; 四、基础操作 1.连接设备 2.命令…

IEEE SPL | 基于图注意力机制的音频语意概述

本文由哈工程智能信号处理组与悉尼科技大学、萨里大学合作&#xff0c;发表于IEEE信号处理学会期刊IEEE Signal Processing Letters&#xff0c;论文一作为2020级硕士研究生肖飞扬。 论文链接&#xff1a;https://arxiv.org/abs/2304.03586 论文代码&#xff1a;https://github…

GPT 任务指令 = 定义角色 + 背景信息 + 任务目标 + 输出要求

GPT 任务指令 定义角色 背景信息 任务目标 输出要求 环境 GPT-4 0. 你是一名专业的导游&#xff0c;负责为我生成旅游计划&#xff0c;现在我来北京旅游&#xff0c;需要你为我生成一份 3天2晚的北京旅游规划。我的要求是&#xff1a;1.地点包括故宫、军播和环球影城。 2…

你一定能看懂的SQL事务及其实现原理

一。概念 事务 是数据库执行原子操作的基本单位。一个事务中的多个修改&#xff0c;则要么全部成功执行&#xff0c;要么全部不执行。 关于事务的 MYSQL 官网的解释 Transactions are atomic units of work that can be *committed* or *rolled back*. When a transaction ma…

substrate实例-基于OCW发送一个签名交易

目录标题 1. 获取substrate-node-template代码2. 添加一个用于测试的ocw-test目录至pallets3. 编写ocw-test/src/lib.rs代码3.1 需要用到的包名的引用3.2 模块crypto的实现3.3 mode pallet 的实现-config、storage、event3.4 mode pallet 的实现-call3.5 mode pallet 的实现-ho…

整理的汉字及拼音、编码数据文件,依据拼音声母进行归类共计2万多条

本篇文章主要讲解自己整理的汉字拼音数据资源的下载及使用方法。 资源截图 包含&#xff1a;sql、xls、txt、json等格式文件 汉字涵盖&#xff1a;多音字、生僻字 下载地址&#xff1a;https://download.csdn.net/download/hj960511/87705416 使用方法 步骤一、下载资源包&…

七、使用arcgis对道路结果进行后处理及iou优化步骤详解

最近在研究对道路的后处理 废话不多说 直接放我的教程了 分别对real真实和predict预测的图片进行镶嵌操作 教程在这里 工具在这里 结果如下 矢量化提取道路中心线 经过很多尝试 arcscan是提取效果最好的一个方法&#xff0c;操作见这 或者这里这篇文章注解更详细一点&am…

问题汇总1

问题汇总 Linux相关1. vim 修改挂载文件时 报错 read-only filesystem2.root 用户密码无法更改3.linux 用户被锁定4.linux 查看登录日志其他小问题 Windows 相关1.添加 删除 默认路由2.exel合并单元格 添加 分隔符 Linux相关 1. vim 修改挂载文件时 报错 read-only filesystem …

Linux namespace

​ 前言 从《initrd&init进程》可知&#xff0c;我们通过ssh连接linux服务器&#xff0c;其实主是linux启动一shell进程与我们做交互。而Linux又是多租户的&#xff0c;这使用得用户与用户间产生了&#xff0c;资源的争抢。 如何隔离资源&#xff0c;且让用户都无法察觉&…

SpringBoot项目实现热部署

文章目录 SpringBoot实现热部署手动开启热部署自动开启热部署热部署相关配置 SpringBoot实现热部署 什么是热部署&#xff1f; 所谓热部署&#xff0c;就是在应用正在运行的时候升级软件&#xff0c;却不需要重新启动应用。对于Java应用程序来说&#xff0c;热部署就是在运行时…

初学数据库

1、什么是数据库 数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库。 每个数据库都有一个或多个不同的API用于创建&#xff0c;访问&#xff0c;管理&#xff0c;搜索和复制所保存的数据。 我们也可以将数据存储在文件中&#xff0c;但是在…

企业级实践:大厂项目研发流程

引言 战国邹孟轲《孟子离娄上》&#xff1a;“离娄之明&#xff0c;公输子之巧&#xff0c;不以规矩&#xff0c;不能成方圆。” 每一个行业都有自己行之有效的规矩&#xff0c;同样软件行业也有自己一套的开发流程&#xff0c;今天就来跟大家聊一聊咱们公司的开发流程&#…

智能修改文案-智能写作平台

智能原创自动写作工具在线 随着人工智能技术的发展&#xff0c;智能原创自动写作工具在线已经成为了网络营销的一个重要工具。这种工具可以根据您输入的关键词和主题&#xff0c;自动生成高质量、原创性强的文章。下面是智能原创自动写作工具在线的优势。 节省时间和人力成本 …

IDEA重复下载SNAPSHOT包问题

问题现象 reimport 之后 状态栏显示resolving dependencies… 遇到某个比较大的快照包(33M)&#xff0c;同一天的第2个版本时 1.0-xxx-SNAPSHOT.时间戳-2 idea importer 会先分片下载 x.jar.part文件中&#xff0c;然后复制为x.jar吧 如图中所示&#xff0c;其实已经下载完了&…

C++四种类型转换运算符

C语言之所以增加强制类型转换的语法&#xff0c;就是为了强调风险&#xff0c;让程序员意识到自己在做什么。 但是&#xff0c;这种强调风险的方式还是比较粗放&#xff0c;粒度比较大&#xff0c;它并没有表明存在什么风险&#xff0c;风险程度如何。再者&#xff0c;C风格的…

深入浅出OkHttp,【带你手写】构建高效、高性能的网络请求框架

简述 OKHttp是一个用Java编写的网络框架&#xff0c;可用于 Android&#xff0c;以及一些基于Java的web应用开发中。它使用了HTTP/2标准的支持和连接池技术&#xff0c;可以让应用快速向Web服务器发送网络请求&#xff0c;并得到响应。OKHttp提供了一个简单的API&#xff0c;允…

【SQL】列的选择与查询

本文内容参考书籍《SQL基础教程》第二章&#xff0c;课后习题在最后&#xff0c;请多指教。之前章节的内容请点击下方链接。 前言 PostgreSQL的下载与安装 第一章 数据库的创建&#xff0c;表的创建、更新、删除 一、SELECT语句 1、查询表中的列 &#xff08;1&#xff09…