“int mask =〜0”的目的是什么?

我在C中看到了下面这行代码

int mask = ~0; 

我用C和C ++打印了mask的值。 它总是打印-1

所以我有一些问题:

  • 为什么赋值~0掩码variables?
  • 〜0的目的是什么?
  • 我们可以使用-1而不是~0吗?

这是一种可移植的方法,可以将整数中的所有二进制位设置为1位,而无需知道当前体系结构中有多less位是整数。

C和C ++允许3种不同的有符号整数格式:符号幅度,补码和二进制补码

无论系统使用什么符号格式,〜0都将产生全部一位。 所以它比-1更便于携带

而且~0表示意图更清楚:将值0中的所有位反转,而-1表示需要减1的值,而不是其二进制表示

在2的补码平台(假定)给你-1,但直接写-1是规则禁止的(只有整数0..255,一元!~和二元&^|+<<>>是允许的)。

你正在研究一个编码挑战,对操作符和语言结构有一些限制,来执行给定的任务。

第一个问题是返回值-1而不使用-运算符。

在用二进制补码表示负数的机器上,值-1表示所有位都设置为1 ,所以~0计算为-1

 /* * minusOne - return a value of -1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 2 * Rating: 1 */ int minusOne(void) { // ~0 = 111...111 = -1 return ~0; } 

文件中的其他问题并不总是正确执行。 第二个问题,返回一个布尔值,表示一个int值适合16位有符号short的事实有一个缺陷:

 /* * fitsShort - return 1 if x can be represented as a * 16-bit, two's complement integer. * Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 8 * Rating: 1 */ int fitsShort(int x) { /* * after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111 * so after shift, if x remains the same, then it means that x can be represent as 16-bit */ return !(((x << 16) >> 16) ^ x); } 

向左移位一个负值或移位值超出int范围的数字具有未定义的行为,右移一个负值是实现定义的,所以上面的解决scheme是不正确的(尽pipe可能是预期的解决scheme)。

Loooong之前,这是如何在非常有限的设备(如1K ZX 80或ZX 81计算机)上保存内存。 在BASIC中,你会的

 Let X = NOT PI 

而不是

 LET X = 0 

由于数字被存储为4个字节的浮点,所以后者比第一个NOT PIselect多2个字节,其中NOT和PI每个都占用一个字节。

所有计算机体系结构都有多种编码方式。 当使用2的补码时,这总是正确的: ~0 == -1 。 另一方面,一些计算机使用1的补码来编码上面的例子不真实的负数,因为~0 == -0 。 是的,1s补码的负值为零,这就是为什么它不是很直观。

所以对你的问题

  • 〜0被分配给掩码,因此掩码中的所有位都等于1 – > mask & sth == sth
  • 无论使用何种平台,〜0都用于使所有位等于1
  • 如果您确定您的计算机平台使用2的补码编码,则可以使用-1而不是〜0

我个人的想法 – 尽可能地让你的代码尽可能地独立于平台。 成本相对较低,代码成为失败certificate