6
char byte = 0xff;
printf("%lu\n", sizeof(byte)) // Output is '1'
printf("%x\n", byte); // Output is 'ffffffff'

如果 的大小byte只有一个字节,那么为什么printf()表现得好像它是四个字节?

4

4 回答 4

15

形式上,您的程序表现出未定义的行为:%x格式规范需要一个类型的参数unsigned int,但您传递的是一个int,如下所述(帽子提示@R)。这在现代二进制补码机器上实际上是无害的,因为 int 和 unsigned 具有兼容的位布局。但同样,从技术上讲,这是未定义的行为,修复它是一个好主意,如printf("%x\n", (unsigned)byte);.

将参数传递给可变参数函数的规则规定,所有小于 int 的整数类型都被提升为 int。否则,如何printf知道%x是从堆栈中抓取一个字节还是四个字节?从标准:

5.2.2p7:
当给定参数没有参数时,参数以接收函数可以通过调用 va_arg 获取参数值的方式(18.10)...传递提升(4.5),或受浮点提升影响的浮点类型(4.6),参数的值在调用之前转换为提升的类型。

这就是你char变成int. 未指定char签名或未签名,但显然,在您使用的平台上,它是签名类型。因此,当提升为int. 0xff(char)-1,并且0xffffffff(int)-1

于 2013-07-24T21:26:20.783 回答
3

我认为这是由于integer promotion

关于这个概念的一篇很好的博客文章:http ://www.idryman.org/blog/2012/11/21/integer-promotion/

于 2013-07-24T21:25:43.667 回答
2

您通过将错误的参数类型传递给printf. 说明%x符需要 type 的参数unsigned int,但您传递了(由于默认促销)签名的int. 如果有符号参数的值是非负的,这可以说是有效的,但是在您的系统上,plain恰好是有符号类型,因此包含将实现定义的转换应用于; 这种转换的通常结果是-1。intcharbyte0xff

于 2013-07-24T23:35:15.720 回答
1

Achar是有符号的 8 位。"%x\n"格式说打印一个整数。所以 的值byte是符号扩展为整数。由于 a charof是,在这种情况下,0xff的 8 位值只是打印 a 的十六进制整数值,即。-1printf-1ffffffff

于 2013-07-24T21:24:14.467 回答