C解释中的钻头操作



我在c:

中具有以下代码
 unsigned int a = 60; /* 60 = 0011 1100 */
 int c = 0;
 c = ~a; /*-61 = 1100 0011 */
 printf("c = ~a = %dn", c );
 c = a << 2; /* 240 = 1111 0000 */
 printf("c = a << 2 = %dn", c );

第一个输出是-61,而第二个输出为240。为什么第一个printf计算两者的补充1100 0011,而第二个则仅将1111 0000转换为其十进制等效的数字?

您假设int只有8位宽。在您的系统上可能不是这种情况,它可能使用16或32位用于int

在第一个示例中,所有位倒转。这实际上是直截了当的,而不是两个的补充:

1111 1111 1111 1111 1111 1111 1100 0011  (32-bit)
                    1111 1111 1100 0011  (16-bit)

在第二个示例中,当您将其向左移动2时,最高点仍然为零。在评论中,您将数字描述为8位,误导了自己。

0000 0000 0000 0000 0000 0000 1111 0000  (32-bit)
                    0000 0000 1111 0000  (16-bit)

尝试避免使用签名的整数进行刻度操作 - 通常会导致您陷入不确定的行为。

这里的情况是,您正在使用未签名的值并将其分配给签名变量。对于~60,这是未定义的行为。您将其视为-61,因为位模式~60也是-61的两个组合表示形式。另一方面,60 << 2出现正确,因为240具有与签名和未签名的整数相同的表示。

最新更新