一位同事对此感到困惑,我无法弄清楚这个C程序实际上是如何编译和运行的。这个>>>=运算符和奇怪的1P1文字是什么?我已经在Clang和GCC中进行了测试。没有警告,输出为“???”

#include <stdio.h>

int main()
{
    int a[2]={ 10, 1 };

    while( a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ] )
        printf("?");

    return 0;
}

最佳答案

该行:

while( a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ] )

包含digraphs :><:,它们分别转换为][,因此等效于:
while( a[ 0xFULL?'\0':-1 ] >>= a[ !!0X.1P1 ] )

文字0xFULL0xF相同(15为十六进制); ULL仅指定it's an unsigned long long literal。无论如何,作为 bool 值是正确的,因此0xFULL ? '\0' : -1的计算结果为'\0',这是一个character literal,其数值仅为0

同时,0X.1P1是等于2/16 = 0.125的hexadecimal floating point literal。无论如何,如果为非零值,则作为 bool 值也是如此,因此再次使用!!对其进行两次否定会生成1。因此,整个过程简化为:
while( a[0] >>= a[1] )

运算符>>=compound assignment,它会将其左操作数向右移右操作数给定的位数,然后返回结果。在这种情况下,右操作数a[1]始终具有值1,因此它等效于:
while( a[0] >>= 1 )

或等效地:
while( a[0] /= 2 )
a[0]的初始值为10。向右移动一次后,它变为5,然后(向下舍入)2,然后是1,最后是0,此时循环结束。因此,循环体将执行三次。

10-08 13:45