一位同事给出了一个谜题,我不知道这个C程序实际上是如何编译和运行的.这个>>>=运算符和奇怪的1P1字面是什么?我在郎和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.在任何情况下,作为一个布尔值,它是真的,所以0xFULL ? '\0' : -1计算为'\0',这是一个character literal,其数值只是0.

同时,0X.1P1hexadecimal floating point literal,等于2/16=0.125.在任何情况下,作为非零,它作为布尔值也是真的,所以用!!求反两次,再次产生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,此时循环结束.因此,循环体执行三次.

C++相关问答推荐

ARM上的Modulo Sim Aarch 64(NEON)

为什么已经设置的值在C中被重置为for循环条件中的新值?

错误:C中需要参数声明符

找出文件是否包含给定的文件签名

在struct中调用函数,但struct在void中 *

将 typewriter LF打印到Windows终端,而不是隐含的CR+LF

变量>;-1如何在C中准确求值?

在C++中使用函数指针的正确语法

为什么cudaFree不需要数据 struct 的地址?

致命:ThreadSaniizer:在Linux内核6.6+上运行时意外的内存映射

如何使用指向 struct 数组的指针并访问数组中特定索引处的 struct

为什么我会收到释放后堆使用错误?

防止C++中递归函数使用堆栈内存

如何在提取的索引中分配空值?

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

关于不同C编译器中的__attribute__支持

指向返回 struct 成员的指针,安全吗?

使用替代日历打印日期

C/C++编译器可以在编译过程中通过按引用传递来优化按值传递吗?