我遇到了以下示例程序,但我并不完全理解它的输出:
#include <stdio.h>
int main( void ) {
unsigned char i, m =0xFF, n=0x1;
for ( i = 0; i != 8; i++,n+=n, m/=2 )
printf("%5x %5x %5x %5x %5x %5x\n", n,m,n&m,n|m,n^m,~n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印出来:
1 ff 1 ff fe fffffffe
2 7f 2 7f 7d fffffffd
4 3f 4 3f 3b fffffffb
8 1f 8 1f 17 fffffff7
10 f 0 1f 1f ffffffef
20 7 0 27 27 ffffffdf
40 3 0 43 43 ffffffbf
80 1 0 81 81 ffffff7f
Run Code Online (Sandbox Code Playgroud)
问题是最后一栏.由于它是unsigned char,我希望它在每列中只打印2个位置. ~n生成一个unsigned char作为结果,但似乎它被转换为带符号的32位值并由符号扩展符号%5x.
怎么可能,这里发生了什么?
Die*_*Epp 10
在算术运算中使用整数类型时会提升它们(printf顺便说一下,这与它无关).
所以,例如,
unsigned char x = 0xff;
int y = ~x; // x is promoted to 0x000000ff, then changed to 0xffffff00
unsigned char z = ~x; // truncated back to 0x00
Run Code Online (Sandbox Code Playgroud)
整数提升会导致各种问题:
unsigned char x = 1;
if (x << 8)
puts("x << 8 is true"); // does print
x <<= 8;
if (x)
puts("x <<= 8 is true"); // does not print
Run Code Online (Sandbox Code Playgroud)
截断事物的两种方法是强制转换和掩码.用你喜欢的任何东西.
unsigned char x = 0xab;
printf("x = %02x\n", (unsigned char) x);
printf("x = %02x\n", x & 0xff);
Run Code Online (Sandbox Code Playgroud)
整数提升并不总是发生,并且它不是唯一的隐式演员.它也有点微妙,准确的规则很难记住.如果你正在使用64位数字,你真的需要担心它,因为1U << 32最终会成为0或者1完全不同.(它通常1在x86上).
| 归档时间: |
|
| 查看次数: |
12185 次 |
| 最近记录: |