Lassen Sie uns den Ausdruck von links nach rechts durchgehen:
a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ]
Das erste, was mir auffällt, ist, dass wir den ternären Operator aus der Verwendung von verwenden ?
. Also der Unterausdruck:
0xFULL ? '\0' : -1
sagt: "Wenn 0xFULL
nicht Null ist, geben Sie '\0'
andernfalls zurück -1
. 0xFULL
ist ein hexadezimales Literal mit dem vorzeichenlosen Long-Long-Suffix - was bedeutet, dass es ein hexadezimales Literal vom Typ ist unsigned long long
. Das ist jedoch nicht wirklich wichtig, da 0xF
es in eine reguläre Ganzzahl passen kann.
Außerdem konvertiert der ternäre Operator die Typen des zweiten und dritten Terms in ihren gemeinsamen Typ. '\0'
wird dann konvertiert int
, was gerecht ist 0
.
Der Wert von 0xF
ist viel größer als Null, also geht er vorbei. Der Ausdruck wird jetzt:
a[ 0 :>>>=a<:!!0X.1P1 ]
Als nächstes :>
ist ein Digraph . Es ist ein Konstrukt, das sich erweitert zu ]
:
a[0 ]>>=a<:!!0X.1P1 ]
>>=
ist der signierte Rechtsschichtbetreiber, wir können das ausräumen a
, um es klarer zu machen.
Darüber hinaus <:
ist ein Digraph, der sich erweitert zu [
:
a[0] >>= a[!!0X.1P1 ]
0X.1P1
ist ein hexadezimales Literal mit einem Exponenten. Aber egal welcher Wert, !!
alles, was nicht Null ist, ist wahr. 0X.1P1
ist 0.125
was nicht Null ist, also wird es:
a[0] >>= a[true]
-> a[0] >>= a[1]
Das >>=
ist der signierte Rechtsschichtbetreiber. Es ändert den Wert seines linken Operanden, indem es seine Bits um den Wert auf der rechten Seite des Operators nach vorne verschiebt. 10
in binär ist 1010
. Also hier sind die Schritte:
01010 >> 1 == 00101
00101 >> 1 == 00010
00010 >> 1 == 00001
00001 >> 1 == 00000
>>=
Gibt das Ergebnis seiner Operation zurück. Solange die Verschiebung a[0]
für jedes Mal, wenn ihre Bits um eins nach rechts verschoben werden, ungleich Null bleibt, wird die Schleife fortgesetzt. Der vierte Versuch ist, wo a[0]
wird 0
, so dass die Schleife nie betreten wird.
Infolgedessen ?
wird dreimal gedruckt.