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

Spr*_*ose 5 c type-conversion kernighan-and-ritchie

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

这是引发我好奇心的例子:

x = x & ~077
Run Code Online (Sandbox Code Playgroud)

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

0000 0000 0011 1111 (16 bit signed int).
Run Code Online (Sandbox Code Playgroud)

然后,这将补充:

1111 1111 1100 0000.
Run Code Online (Sandbox Code Playgroud)

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

1111 1111 1111 1111 1111 1111 1100 0000
Run Code Online (Sandbox Code Playgroud)

以下2s补充以保留标志.它是否正确?

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

0000 0000 0000 0000 1111 1111 1100 0000
Run Code Online (Sandbox Code Playgroud)

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

1111 1111 1111 1111 1111 1111 1100 0000
Run Code Online (Sandbox Code Playgroud)

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

任何帮助都可以帮助我澄清这个操作是否总是只将最后6位设置为零.

060*_*002 4

无论您选择哪种数据类型,~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
Run Code Online (Sandbox Code Playgroud)

案例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
Run Code Online (Sandbox Code Playgroud)

案例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
Run Code Online (Sandbox Code Playgroud)

案例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
Run Code Online (Sandbox Code Playgroud)

请参阅此处的代码。这意味着当源为 时,符号扩展已完成signed。当源为 时unsigned,符号位不扩展,左侧位设置为0