Это известно как «запутывание»: написание ненужного сложного кода, чтобы сделать что-то более продвинутым, чем оно есть.
Глядя на подвыражение x<<x<<x
, это простые логические сдвиги влево. оператор ассоциативности операторов сдвига слева направо, поэтому выражение равно (x<<x)<<x
.
Мы вышли из смены
2 на 2 и получим 8. 8 << 2
, сдвиг влево на 8 и получим 32:
x = 32 | 32 | (x << !!x) | !!x ;
Тогда для любого выражения с побитовым ИЛИ 32 | 32
, где операнды 32
идентичны, это то же самое, что просто написать 32
без ИЛИ. Так что это эквивалентно:
x = 32 | (x << !!x) | !!x ;
!!
- довольно распространенный, хотя и неясный прием в C для преобразования любого целого числа в логическое значение 0 или 1. !!
- это не один оператор, а два раза логический оператор not !
. Сначала у нас есть !2
, что 0
. Тогда !0
, что дает 1
. Нам осталось это:
x = 32 | (2 << 1) | 1;
2 << 1
равно 4, поэтому:
x = 32 | 4 | 1;
Запишите это в двоичном виде:
0010 0000
OR 0000 0100
OR 0000 0001
------------
0010 0101 = 0x25 hex = 37 dec