同僚からパズルとして提示されたこの 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;
}
ベストアンサー1
この線:
while( a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ] )
含まれる二重音字 :>
およびはそれぞれおよび<:
に変換されるため、次の式と同等になります。]
[
while( a[ 0xFULL?'\0':-1 ] >>= a[ !!0X.1P1 ] )
リテラルは( の16進数)0xFULL
と同じです。は、0xF
15
ULL
それはunsigned long long
文字通りいずれにしても、ブール値としては真なので、 は と0xFULL ? '\0' : -1
評価され'\0'
、これは文字リテラルその数値は単純に です0
。
0X.1P1
一方、16進浮動小数点リテラル2/16 = 0.125 に等しい。いずれにしても、非ゼロなのでブール値としても真なので、これを再度 で 2 回否定すると が!!
生成されます1
。したがって、全体を次のように簡略化できます。
while( a[0] >>= a[1] )
オペレーター>>=
は複合割り当てこれは、左オペランドを右オペランドで指定されたビット数だけ右にビットシフトし、結果を返します。この場合、右オペランドのa[1]
値は必ず なので1
、次の式と同等になります。
while( a[0] >>= 1 )
または、同等に:
while( a[0] /= 2 )
の初期値はa[0]
10 です。右に 1 回シフトすると 5、次に (切り捨てで) 2、次に 1、最後に 0 になり、その時点でループが終了します。したがって、ループ本体は 3 回実行されます。