一位同事对此感到困惑,我无法弄清楚这个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 ] )
文字
0xFULL
与0xF
相同(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,此时循环结束。因此,循环体将执行三次。