左から右に式を見てみましょう:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
最初に気づいたのは、の使用から三項演算子を使用していることです?
。したがって、部分式:
0xFULL ? '\0' : -1
は、「0xFULL
ゼロ以外の場合はを返し'\0'
、それ以外の場合は-1
。0xFULL
は、符号なしlong-longサフィックス付きの16進数リテラルですunsigned long long
。つまり、のタイプの16進数リテラルであることを意味します。ただし、0xF
通常の整数の内部に収まるので、実際には問題ではありません。
また、三項演算子は、第2項と第3項の型を共通の型に変換します。'\0'
その後に変換されるint
だけです、0
。
の値は0xF
ゼロよりかなり大きいので、合格です。式は次のようになります。
a[ 0 :>>>=a<:!!0X.1P1 ]
次は、:>
ある有向グラフ。これは、次のように展開される構成です]
。
a[0 ]>>=a<:!!0X.1P1 ]
>>=
符号付き右シフト演算子a
です。スペースを空けて明確にすることができます。
さらに、次の<:
ように拡張されるダイグラフです[
。
a[0] >>= a[!!0X.1P1 ]
0X.1P1
指数付きの16進リテラルです。しかし、値に関係なく、!!
ゼロ以外のすべてのものは真です。0X.1P1
は0.125
非ゼロなので、次のようになります。
a[0] >>= a[true]
-> a[0] >>= a[1]
>>=
符号付き右シフト演算子です。演算子の右側の値だけビットを前方にシフトすることにより、左のオペランドの値を変更します。10
バイナリでは1010
です。だからここにステップがあります:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=
その演算の結果を返すためa[0]
、ビットが1つ右にシフトされるたびにシフトがゼロ以外である限り、ループは継続します。4回目の試行は、a[0]
がになる場所な0
ので、ループには入りません。
その結果、?
3回印刷されます。