有人可以解释一下这些C运算符吗?

3

那只是一个位翻转器,笑点在哪里? - undefined
请查看此链接以获取已删除注释的内容:http://www.bsdlover.cn/study/UnixTree/V6/usr/sys/ken/slp.c.html - undefined
5个回答

6
你们这些年轻的小辈出生得太晚了 :)

这段代码来自Unix早期版本(V7之前)。笑话是在它上面的注释是"你不应该理解这个", 这已经成为一个传说


1
两个链接自2014年以来都已失效,存档链接为:https://web.archive.org/web/20141204124808/http://cm.bell-labs.com/cm/cs/who/dmr/odd.html,https://web.archive.org/web/20120324034620/http://minnie.tuhs.org/TUHS/Usenet/notunderstand.txt 另一个关于这个传奇的来源是:https://thenewstack.io/not-expected-understand-explainer/ 和详细讲解的演讲:https://www.youtube.com/watch?v=5HTS_MJ4C30 - undefined

5

~按位取反运算符,它会翻转整数中的位。

然而,在阅读评论并意识到我错误地读取了你的代码后,我意识到你提供的代码在现代编译器中甚至都无法编译。

感谢@Avi:运算符=&的含义与今天的&=相同,但这种语法确实早于当前的C标准,因此它是真正古老的UNIX代码。

今天它真正的含义是什么

这里的&应该作为地址运算符,而不是按位与运算符

int main()
{
    int x = 5;
    int y = 2;
    x =& ~y;
}

编译此代码将产生以下结果:
错误:需要左值作为一元“&”操作数
我真的认为这是一个传输问题,因为从逻辑上讲,应该是 &= 而不是反过来。
如果实际上是 &=,那么它正在执行按位与。

2
但是例子是=&而不是&= - undefined
2
在早期的C语言中,赋值运算符的操作符位于右侧。因此,=&代替了&==+代替了+= - undefined
2
他们改变了它,因为它不明确 - x=-3 可能意味着 x = -3 或者 将 x 减去 3 - undefined

5

在早期的C语言中,赋值运算符是右侧放操作符的。因此,=&被替换为&==+被替换为+=

因此,这段代码只是检查某个特定的位是否设置,如果设置了,则执行相应的操作并关闭该位。


3

=&实际上是两个分开的运算符:=&,所以这一行等同于rp->p_flag = & ~SSWAP;

~按位取反运算符,因此~SSWAP将翻转SSWAP的位。& ~SSWAP将导致对~SSWAP结果的引用,这是一个编译错误。因此,使用现代编译器(自C89以来)无法编译,但是=&在现代编译器上等同于&=

&=rp->p_flag~SSWAP进行按位与操作,并将结果放入rp->p_flag中。最终结果是,如果设置了SSWAP中的所有0位,则关闭rp->p_flag中相应的位。仅当至少有一个1位被关闭时,才会执行此操作,以便仅在rp->p_flag的值由于此操作而更改时才调用aretu(u.u_ssav)


额,实际上当&直接跟在=后面时,它被用作一元运算符,所以它是取地址运算符,而不是按位与。当然,对临时变量取地址毫无意义,所以很明显这是一个笔误,应该使用&=(这是一个运算符)。 - undefined
@sepp2k 在我看到你的评论之前,我突然想到了。如果你不介意的话,我打算将这个纳入我的回答中。 - undefined
自C89以来,运算符=&已经不存在了。只有运算符&=是有效的。在早期的C编译器中,这实际上是有效的,所以这段代码真的来自于早期的UNIX源代码。 - undefined

2
权威消息中得知:
B引入了广义赋值运算符,使用x=+y将y加到x上。这种表示法来自Algol 68 [Wijngaarden 75],通过McIlroy传播,并被纳入他的版本的TMG中。(在B和早期的C中,该运算符的拼写方式是=+而不是+=;这个错误在1976年得到修复,是由于以一种诱人的简单方式处理B的词法分析器中的第一个形式所致。)

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