在使用C语言过程中可能需要接触长整数类型,其中包括固定长度数据类型的声明、输入输出函数的标志符等细节,在此记录。

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 声明实现的。  

 

  

相应格式字符串

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

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。

  

  实际上,各个格式化标志符的定义在头文件inttypes.h中。可以看到,实际可直接使用格式化标志符%I64d来输出 uint64_t类型。

  

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

scanf输入

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

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

  

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 中确认具体的定义后再根据具体的定义使用对应的格式化标识符。

其他

  在程序设计时需要注意常数的类型问题,笔者在书写简单的测试程序时,使用如下方式,编译器报错"warning: left shift count >= width of type",即左移的长度大于了类型长度。

  

  这是由于C对常数的类型确认机制决定的。整数类型常量由其值和符号共同决定。其中十进制常量的类型是 int 、 long 和 long long 中能够容纳该常量的最小长度类型。故而上例中 1 被确认为 int 类型,长度在本机器上为 32bits,故而在进行编译时会出现错误。相应的,八进制和十六进制常量的类型是能容纳其值的 int 、unsigned int  、long 、unsigned long 、long long 和 unsigned long long 中长度最小的类型。这里可以看到,十进制常量均为有符号类型,而八进制和十进制常量的类型有可能为无符号类型。

  参考: C data types - Wikipedia

      stackoverflow printf and %llx in GCC under Windows 64x

最新文章

  1. python获取命令行输出结果
  2. 用dos命令备份和恢复sql server 数据库
  3. pgpool介绍和安装经验
  4. SSH建立连接的过程
  5. java.util.logging.Logger 使用详解
  6. 关于delphi Assigned
  7. api接口通信安全性
  8. Java编程性能优化一
  9. (转)sql中 in 、not in 、exists、not exists 用法和差别
  10. WPF 三态按钮(PNG贴图)
  11. SRAM,SDRAM,网卡
  12. Java生成文件
  13. BZOJ 4818 SDOI2017 序列计数
  14. Tomcat下wtpwebapps文件夹 和 webapps文件夹区别
  15. SpringCloud-day05-服务调用Ribbon
  16. js中变量名加“-” new Vue()不执行
  17. smbclient和mount -t cifs共享win的共享文件夹? autocad小记
  18. 从npm到vue和nodejs
  19. vm virtualBox下 centos7 Linux系统 与本地 window 系统 网络连接 配置
  20. 每日英语:Do Bicycle Helmet Laws Really Make Riders Safer?

热门文章

  1. oracle 数据库添加Java方法
  2. Markdown 语法整理大集合2017
  3. WPF 小知识点001
  4. PowerDesigner常用设置
  5. 九: 操作提示(js版本)
  6. 联想G480安装固态硬盘过程
  7. 如鹏网学习笔记(十二)HTML5
  8. async和await理解代码
  9. android 模拟器无法启动问题
  10. poj 1811 Prime Test 大数素数测试+大数因子分解