类型转换:在C中将int签名为unsigned long

时间:2013-12-03 07:42:25

标签: c type-conversion kernighan-and-ritchie

我目前正在阅读C语言程序设计语言(K& R)的第2章并阅读有关按位操作的内容。

这是激起我好奇心的例子:

x = x & ~077

假设一个16位字长和32位长字型,我认为会发生077首先转换为:

0000 0000 0011 1111 (16 bit signed int).

然后补充:

1111 1111 1100 0000.

我的问题是x的不同可能类型接下来会发生什么?如果x是带符号的int,那么答案是微不足道的。但是,如果x是有符号长的,我假设〜077将成为:

1111 1111 1111 1111 1111 1111 1100 0000

以下2s补充以保留标志。这是对的吗?

另外,如果x是无符号长整数,则〜077将变为:

0000 0000 0000 0000 1111 1111 1100 0000

或者,将~077转换为签名的长第一个:

1111 1111 1111 1111 1111 1111 1100 0000

...之后它被转换为无符号长(不改变为位)?

任何帮助都可以帮助我澄清此操作是否始终仅将最后6位设置为零。

2 个答案:

答案 0 :(得分:3)

无论您选择何种数据类型,~077都会将最右边的6位设置为0,将所有其他位设置为1

假设有16位int和32位long,则有4种情况:

案例1

unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000

案例2

unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000

案例3

int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000

案例4

int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000

请参阅代码here。这意味着当源为signed时,符号扩展就完成了。当源为unsigned时,符号位不会扩展,左侧位设置为0

答案 1 :(得分:2)

 x = x & ~077    //~077=11111111111111111111111111000000(not in every case)

~077 is a constant evaluated at the complie time so its value will be casted according to the value of x at the compile time所以AND操作总是会产生x的最后6位为0,其余的位将保持在AND操作之前的任何位。喜欢

//let x=256472--> Binary--> 0000 0000 0000 0011 1110 1001 1101 1000
 x = x & ~077;
// now x = 0000 0000 0000 0011 1110 1001 1100 0000 Decimal--> 256448

因此,无论编译时数据类型如何,最后6位都会更改为0,其余位保持不变。在knr中,它写在那里The portable form involves no extra cost, since ~077 is a constant expression that can be evaluated at compile time.