“i” 真的等价于 “i != -1” 吗?

7

~i在C++中是什么意思?

我刚注意到它等价于i != -1,但我不确定。

int arr[3] {1, 2, 3};
int n = 3;
for (int i = n - 1; ~i; i--) {
    cout << arr[i] << ' ';
}

它将数组以相反的顺序打印出来。


1
~ 运算符仅仅是反转操作数的所有位。 - Jabberwocky
1
~ 反转所有位。在二进制补码中,当所有位都被设置时, -1 就是这个数。因此,当你反转所有位时,所有位都被重置,这会得到 0。这就是你的 for 循环的 false 强制转换。 - Blaze
@故事讲述者:该问题的答案在那个页面上_任何地方_都找不到。 - Lightness Races in Orbit
4
这是一种使用混淆方式非常依赖具体实现的方法来编写测试i != -1 - StoryTeller - Unslander Monica
2
@HossamKamil 竞赛编程中不允许使用优化器吗? - eerorika
显示剩余8条评论
3个回答

14

~是按位取反运算符。当且仅当i的所有位都为1时,~i的值为0。关于-1是否具有所有位都为1,取决于如何在系统中表示有符号数。在二进制补码表示法中,-1用所有位都为1来表示,因此在这种系统中,~(-1) == 0。在一补数和二进制原码中都不成立。

因此,答案是否定的,不能在所有系统上成立。话虽如此,在现代机器(自90年代以来生产的所有机器)中,二进制补码相当普遍,因此在这种系统中,答案是肯定的。无论符号表示如何,i != -1更易读。


请注意:https://dev59.com/7LTma4cB1Zd3GeqP7Hzh#56589637 我知道这是不同的操作,但几乎可以肯定适用相同的规则。也就是说,在C++20中保证了类似于二进制补码的行为,在此之前几乎隐含需要这样的行为。 - Lightness Races in Orbit
@LightnessRacesinOrbit,“pretty-much-implied-to-be-required-anyway”是什么意思?除了在C++20之前的固定宽度整数操作之外,没有要求操作行为像二进制补码。 - eerorika
请点击提供的链接。 - Lightness Races in Orbit
@LightnessRacesinOrbit 那么它的哪一部分解释了“几乎被暗示为必需,就像它是二进制补码一样”? - eerorika
@LightnessRacesinOrbit 适用于我所了解的大多数有符号数表示方式,而不仅仅是2的补码的那种? - eerorika
显示剩余3条评论

5

~i 是按位取反运算符。也就是说,它会翻转 i 中的每一位。

-1 的二进制表示是将数字的每一位都设置为 1,将每一位取反得到的结果是 0。当在需要布尔值的位置检查整数时,0 被视为 false,任何其他数字被视为 true

因此,在这种特殊情况下,~i 等同于 i != -1


3
你应该提到整数表示是依赖于实现的... 没有保证-1被表示为所有位都设置为 1。 - BiagioF
1
在二进制补码系统中,它是以这种方式表示的。C++(仍然)支持其他数字表示法(尽管这些已经不常见了)。我建议您在这一点上进行更详细的阐述。 - StoryTeller - Unslander Monica

0
因为您的 for 循环的 i 变量是 int 类型,它被定义为有符号整数,因此在二进制补码中,其值为-1时的二进制表示方式是所有位都设置为1,这意味着所有位都是1。另一方面,所有1的按位取反是所有零,这是您需要的,循环执行直到i>=0或i!=-1,因为您正在递减i。 在系统上对符号值进行位运算的上下文中,int 的二进制补码表示是相同的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接