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

【genius_platform软件平台开发】第九十四讲:int64_t的格式化问题(lld和PRId64)

  • 问题起因是在进行上位机软件优化的工作安排时,同事对unsigned long long 类型的时间戳进行了格式化输出优化,从%ull优化为了% PRIu64,我进行代码合并请求处理的时候突然感觉这个可以仔细查一下。查阅到的相关资料如下:
    *在这里插入图片描述

1. int64_t 与 uint64_t

  • C的标准只规定特定数据类型需要实现的最小长度,特定类型的具体长度取决于编译器实现。为了增强程序的可移植性,C99标准增加了对固定长度的整数类型的支持。
  • 对固定长度类型的定义位于头文件 stdint.h 中。其中包括固定长度有符号整数类型 intN_t 和固定长度无符号整数类型 uintN_t,分别表示固定占用 N bits长度的整数类型( N = 8、16、32、64)。

  • 图示为CodeBlock13.12中头文件 stdint.h 对 int64_t 和 uint64_t 的定义,可以看到它们是通过对 long long 和 unsigned long long 的 typedef 声明实现的。  

2. 相应格式字符串

  • 对于定义在头文件 stdint.h 中的类型 ,其printf和scanf的格式字符串在头文件 inttypes.h 中实现。

3. printf输出

  • 对于printf使用的格式化标识符,一般格式为 PRI + format + type 。其中 format规定输出的格式,可以为 d( decimal ,十进制) 、h( hexadecimal ,十六进制) 、o( octal , 八进制)、u( unsigned ,无符号)等,type 为对应的数据类型,可以为 N 。( 实际type还可以为FASTN、LEASTN、PTR 和 MAX等,具体可见 C data types - Wikipedia ) 如对于int64_t数据类型的输出,可以使用格式标志符 PRId64。
    在这里插入图片描述

  • 这也从解释了为什么需要将 PRIu64 独立书写,这是由于使用格式化字符串" %PRIu64 “时,编译器会将 " " 间的所有字符均视为字符串的一部分,这样在预处理阶段便无法对 PRIu64 的宏定义进行替换。将PRIu64独立出来后,其会在预编译阶段被替换为” I64u " (注意这里替换的结果包含引号),即格式化字符串变为 " % " " I64u " “\n”,在C语言中被当作“ %I64u\n”处理,从而保证结果正确输出。

4. scanf输入

  • 对应的scanf使用的格式化标识符,一般格式为 SCN + format + type。其中 format规定输出的格式,可以为 d( decimal ,十进制) 、h( hexadecimal ,十六进制) 、o( octal , 八进制)、u( unsigned ,无符号)等,type 为对应的数据类型,可以为 N 。

  • scanf的格式化标志符与printf中的定义方法大致相同,在头文件 inttypes.h 中存在相应的宏定义,如对无符号类型的输入的标识符如下图所示
      在这里插入图片描述

5. unsigned long long 与 long long 类型的输入与输出

  • 在CodeBlocks的头文件 stdint.h 中存在如下表述:
      在这里插入图片描述

  • 一般而言C语言标准给出的 unsgned long long 与 long long 的格式化标识符分别为 llu 与 lli,但实在Windows环境下编译时,可能尚未提供对 " ll " 格式化标志符的支持,使得使用了以上两种格式化标识符的类型无法被正确识别。一种可行的解决方法是使用上述 int64_t 与 uint64_t 的格式化标识符,因为从头文件 stdint.h 的定义中我们可以发现,int64_t 与 uint64_t 分别就是 long long 与 unsigned long long 的 typedef 定义,故而可以使用 PRId64 和 PRIu64 来对 long long 类型与 unsigned long long 类型进行输出。

  • 需要注意的是,不同的机器和编译器对 int64_t 和 uint64_t 的实现可能并不相同,故而最好先在头文件 stdint.h 中确认具体的定义后再根据具体的定义使用对应的格式化标识符。

http://www.lryc.cn/news/63438.html

相关文章:

  • 多模态之clip
  • Lombok常用注解
  • 加拿大各省接受公立教育的初始年龄汇总 — 供携子女赴加的访学、博后参考
  • 数字化工厂:虹科Vuzix AR眼镜在工业制造中的革新应用
  • 配置出接口方式的单服务器智能DNS
  • 数据结构初阶(栈和队列)
  • IDEA实用设置
  • 关联爆破-RSA分解
  • Netty内存管理--内存池PoolArena
  • RabbitMQ 发布订阅模式,routing路由模式,topic模式
  • 又一款可视化神器,开源了!
  • 干货 | 中科院心理所考研复试经验分享
  • Redis基础知识概述
  • 开心档之C++ 引用
  • 后台优化主要分为哪些?工作内容及流程是什么?
  • 二叉树及其遍历
  • java 版本企业电子招投标采购系统源码之登录页面
  • 第五章 使用RAID与LVM磁盘阵列技术
  • LeetCode 560. 和为 K 的子数组
  • 后端要一次性返回我10万条数据
  • 汽车智能化「出海」红利
  • Windows10资源管理器使用
  • 【视频教程解读】Window上安装和使用autogluon V0.7
  • 10、Java继承与多态 - 内部类的概念与分类 1
  • Java SE 面试题
  • Linux 之十九 编译工具链、.MAP 文件、.LST 文件
  • 小 C 的数学(math)
  • 应用运行环境实时洞察,亚马逊云科技Cisco AppDynamics展优势
  • C++程序设计——lambda表达式
  • Unity 高级程序员应该具备怎样的能力?要怎样成长为 Unity 高级程序员?