简体   繁体   English

短x = -123; printf(“%x \\ n”,x >> 3);

[英]short x = -123; printf(“%x\n”, x>>3);

short x = -123;
unsigned short y = -123;

printf("%x\n", x>>3);
printf("%x\n", y>>3);

The result was 结果是

fffffff0
1ff0

I don't understand the first result because short is 2 bytes but the result was 4 bytes. 我不明白第一个结果,因为short是2个字节,但结果是4个字节。

The %x format specifier expects an unsigned int argument. %x格式说明符需要unsigned int参数。 Passing any other type of argument ( even int ) causes undefined behaviour. 传递任何其他类型的参数( 甚至是int )会导致未定义的行为。

You could modify your code to: 您可以将代码修改为:

printf("%x\n", (unsigned int)(x>>3));
printf("%x\n", (unsigned int)(y>>3));

For x >> 3 , first of all x undergoes integer promotion. 对于x >> 3 ,首先x经历整数提升。 This turns (short)-123 into (int)-123 because promotions are value-preserving. 这会将(short)-123变成(int)-123因为促销是保值的。

Then -123 >> 3 causes implementation-defined behaviour. 然后-123 >> 3导致实现定义的行为。 Probably your implementation defines it as an arithmetic right shift on the 2's complement representation in 32-bit integers: 可能你的实现将它定义为32位整数中2的补码表示的算术右移:

-123:         11111111111111111111111110000101
-123 >> 3: 11111111111111111111111111110000

which is -16 in 2's complement. 这是-16 in 2的补码。

Finally, (unsigned int)-16 is defined as meaning UINT_MAX - 15 . 最后, (unsigned int)-16定义为UINT_MAX - 15 0xFFFFFFFF - 15 gives 0xFFFFFFF0 . 0xFFFFFFFF - 15给出0xFFFFFFF0


For the unsigned short y = -123; 对于unsigned short y = -123; line, -123 is converted to unsigned short , giving value for y on your system of USHRT_MAX - 122 which is 65413 . line, -123转换为unsigned short ,在你的USHRT_MAX - 122系统上为y给出值,即65413 Then for y >> 3 , this value is promoted to int , retaining the value 65413 . 然后对于y >> 3 ,该值被提升为int ,保留值65413 The definition of right-shift for positive numbers is to divide by 2 that many times. 正数的右移定义是多次除以2 65413/8 gives 8176 which is 1FF0 in hex. 65413/8给出8176 ,其为十六进制的1FF0

I don't understand the first result because short is 2 bytes but the result was 4 bytes. 我不明白第一个结果,因为short是2个字节,但结果是4个字节。

First of all, the >> operator causes implicit integer promotion of both operands to int , unless they weren't already of a larger type. 首先, >>运算符导致两个操作数的隐式整数提升int ,除非它们不是更大的类型。 The resulting type of the expression is that of the promoted left operand. 结果表达式的类型是提升的左操作数的类型。

Even without the shift operator, all small integer types that are passed to variable-argument functions such as printf, undergo a similar form of implicit integer promotion (the default argument promotion rule) to int . 即使没有移位运算符,所有传递给变量参数函数(如printf)的小整数类型也会经历类似形式的隐式整数提升(默认参数提升规则)到int

This is the reasons why you get 4 bytes. 这就是你获得4个字节的原因。

As for why the values are printed in the way they are, see the answer by MM Your code is using the incorrect format specifiers and relies on various forms of poorly-specified behavior, so anything can happen. 至于为什么值以它们的方式打印,请参阅MM的答案您的代码使用了不正确的格式说明符,并依赖于各种形式的不良指定行为,因此任何事情都可能发生。

Not specifying a modifier for your format in printf indicate you want the default int to be printed ( regardless of the length of the value you are passing ). 不在printf为您的格式指定修饰符表示您希望打印默认的int (无论您传递的值的长度如何)。

you can refer to this printf reference , especially the specifier list to indicate to printf what is the length you desire. 你可以参考这个printf参考 ,特别是说明者列表,以指示printf你想要的长度。 In your case you wanted a "%hx" format. 在您的情况下,您想要一个"%hx"格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM