what is the correct format for a 1 byte signed number?

%hh和您选择的整数转换说明符(例如,?hhX.请参阅C11标准,§7.21.6.1p5:

hh

Specifies that a following d, i, o, u, x, or X conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing);…

带括号的注释很重要.由于对可变参数函数(例如printf)的参数的整数提升,函数永远不会看到char参数.许多程序员认为这意味着不必使用h和hh限定符.当然,你不会通过将它们排除在外来创建未定义的行为,并且大部分时间它都会起作用.

但是,char可能会被签名,整数提升将保留其值,这将使其成为有符号整数.使用无符号格式(例如?X)打印带符号的整数将显示符号扩展的Fs.因此,如果要使用无符号格式显示带符号的字符,则需要告诉printf整数类型的原始未提升宽度是什么,使用hh.

如果不清楚,一个简单的例子(但有争议的)例子:

/* Read the comments thread to this post; I'll remove

this note when I edit the outcome of the discussion into

the answer

*/

#include

int main(void) {

char* s = "\u00d1"; /* Ñ */

for (char* p = s; *p; ++p) printf("%02X (%02hhX)\n", *p, *p);

return 0;

}

输出:

$./a.out

FFFFFFC3 (C3)

FFFFFF91 (91)

在注释线程中,存在(或者可能是)关于上述片段是否是未定义行为的相当大的讨论,因为X格式规范需要无符号参数,而char参数(至少在生成呈现输出的实现上)签名.我认为这个论点依赖于§7.12.6.1/ p9:“如果任何参数不是相应转换规范的正确类型,则行为是未定义的.”

但是,在char(和short)整数类型的情况下,在调用函数之前,参数列表中的表达式将提升为int或unsigned int. (值得注意的是,在大多数体系结构中,所有三种字符类型都将被提升为signed int;将unsigned char(或unsigned char)提升为unsigned int只会在sizeof(int)== 1的实现上发生.)

因此,在大多数体系结构中,%hx或%hhx格式转换的参数将被签名,并且如果不使这些格式代码的使用毫无意义,则不能使用未定义的行为.

此外,标准并没有说fprintf(和朋友)会以某种方式恢复原始表达.它所说的是“在打印之前应将值”转换为带符号的字符或无符号字符“(§7.21.6.1/ p5,上面引用,强调添加).

将有符号值转换为无符号值不是未定义的.它甚至没有指定或依赖于实现.它只是(概念上)“重复地加上或减去一个可以在新类型中表示的最大值,直到该值在新类型的范围内”. (§6.3.1.3/ P2)

因此,有一个定义明确的过程将参数表达式转换为(可能已签名的)int参数,以及一个定义良好的过程,用于将该值转换为unsigned char.因此,我认为像上面提到的那样的程序是完全明确的.

为了确证,给定格式说明符%c的fprintf的行为定义如下(§7.21.6.8/ p8),重点补充:

the int argument is converted to an unsigned char, and the resulting character is written.

如果要应用拟议的限制性解释,使上述程序不明确,那么我相信人们也会被迫也认为:

void f(char c) {

printf("This is a '%c'.\n", c);

}

也是UB.然而,我认为几乎每个C程序员都写了类似的东西而没有考虑过它.

问题的关键部分是§7.12.6.1/ p9(以及§7.12.6.1的其他部分)中“论证”的含义. C标准稍微精确一些;它指定如果参数受默认参数提升的影响,“参数的值将在调用之前转换为提升类型”,我将其解释为表示在考虑调用时(例如,调用fprintf),参数现在是提升的值.

我不认为C实际上是不同的,至少在意图上.它使用的措辞如“争论和解决方案;被提升”,并在至少一个地方“推广后的论点”.此外,在变量函数的描述中(va_arg宏,§7.16.1.1),对参数类型的约束以括号方式注释“实际下一个参数的类型(根据默认参数提升而提升)”.

我会自由地同意所有这些都是(a)微妙地阅读不够精确的语言,以及(b)计算舞蹈天使.但是我没有看到任何声明像使用带有char参数的%c这样的标准用法是“技术上”UB的价值;这证明了UB的概念,很难相信这样的禁令是故意的,这让我相信这种解释不是故意的. (也许,应该在编辑上予以纠正.)

c语言printf格式限定符,c – 1字节有符号数的printf格式相关推荐

  1. Unity3D C#中 String.Format的格式限定符

    Format方法将多个对象格式化成一个字符串Format方法解析格式字符串的原理: (1).格式字符串中的{0}会被替换成格式字符串之后的第一个参数,以此类推 (2).Format方法解析格式字符串时 ...

  2. c语言换行符不起作用,回车符与换行符问题——C语言

    回车符(carriage return,'\r')与换行符 (line feed,'\n') 换行对应的ASCII码值是10,回车符对应的ASCII码值是13,需要注意的是用户按下回车键时,对于不同的 ...

  3. R语言使用haven包的read_spss函数读取spss格式数据、使用haven包的read_sas函数读取SAS格式数据、使用haven包的read_dta函数读取Stata格式数据

    R语言使用haven包的read_spss函数读取spss格式数据.使用haven包的read_sas函数读取SAS格式数据.使用haven包的read_dta函数读取Stata格式数据 目录

  4. linux中的shell有printf吗,Linux Shell系列教程之(八)Shell printf命令详解

    在上一篇:Linux Shell系列教程之(七)Shell输出这篇文章中,已经对Shell printf命令有了一个简略的介绍,本篇给大家详细介绍下Shell中的printf命令. 一.Shell p ...

  5. 数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11

    这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段.这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了. 这段代码,我用 ...

  6. FFmpeg之视频封装格式、流媒体协议、视频编解码协议和传输流格式、时间戳和时间基、视频像素数据

    通用视频分析工具:Mediainfo.Elecard StreamEye(视频编码分析工具); 视频封装格式: ********************MP4****************** MP ...

  7. java 内部类 返回值_Java基础第10天+形式参数和返回值的问题、包、导包、权限修饰符、常见的修饰符、内部类(局部内部类,成员内部类,匿名内部类)...

    1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返回值类型: 类名:返回的是该类的对象 抽象类名:返回的 ...

  8. 80x86描述符总结及解析描述符的小程序

    一.描述符的分类 二.描述符格式 1.数据段描述符 2.代码段描述符 3.LDT段描述符 4.TSS段描述符 5.调用门描述符 6.中断门描述符 7.陷阱门描述符 8.任务门描述符 三.解析描述符的小 ...

  9. 服务器怎样修改盘符,服务器怎样修改盘符

    服务器怎样修改盘符 内容精选 换一换 对于挂载了SCSI类型云硬盘的Linux弹性云服务器,如果在/etc/fstab中配置了SCSI磁盘开机自动挂载,且使用的是磁盘的盘符(如/dev/sdb)进行配 ...

最新文章

  1. DWZ与KindEditor编辑器的整合
  2. pointnet分割自己的点云数据_点云学习历史文章大汇总
  3. (更新)网络规划设计师考试大纲 及教程_下载
  4. 为什么matlab显示error,【求救】我安装了资源 MATLAB R2012b 后,显示有error……
  5. PAT_B_1026_Java(15分)
  6. aix升级openssh_AIX5.3如何安装openssh | 学步园
  7. 为什么都建议学java而不是python-为什么都建议学Java而不是Python?两者有什么区别吗?...
  8. Windows核心编程_Edit控件无法输入问题
  9. Django 从0开始创建一个项目
  10. dnf电脑服务器不稳定怎么办,Win10玩DNF间歇性卡顿怎么办?Win10系统玩DNF卡顿解决方法(2)...
  11. JAVA自动生成前缀加日期的编码
  12. 对话投资人刘芹:认知不够,才不敢做疯狂的事
  13. 2020 中国移动的流量套餐
  14. 如何在网页中添加 GitHub Corners
  15. Vue + vite 切换 favicon图标
  16. PHPcurl请求很慢解决办法
  17. 位操作 、|、~、^、、
  18. bzoj4605 崂山白花蛇草水(动态开点线段树逃替罪羊重构K-D tree)
  19. js经验分享 JavaScript反调试技巧
  20. 爆笑课堂:程序员看得懂的搞笑段子

热门文章

  1. 34岁的困境!测试工程师如何突破职业瓶颈?
  2. Intranet/Internet
  3. 42所双一流高校,都是如何处理学术不端行为的?
  4. python vue+flask 跨域请求
  5. ArcGIS教程:要素类基础知识(一)
  6. VS2019+WDK10编写xp平台的驱动
  7. With...As 用法--公用表达式
  8. 法线向量扰动、副法线
  9. 最齐全的电子数码3d打印模型素材,速来收藏
  10. 技术人从职场中脱颖而出的成长秘诀