Ну,
1<<i
должно быть 1, за которым следуют нули (двоичные) - так что
1<<0 = 0001
1<<1 = 0010
1<<2 = 0100
Когда это ORed с тем, что в C, это означает принудительно установитьэтот бит, так:
if you take 0000 | 0010 you'll get 0010
c val| mask = result
--------------------
0010 | 0010 = 0010 as well
1111 | 0010 = 1111 (No change if the bit is already 1)
1101 | 0010 = 1111 (Just sets that one bit)
xxxx | 0010 = xx1x (All the other bits remain the same)
Наконец, он сохраняет результат обратно в c.
Таким образом, по сути, он устанавливает i-й бит в c (начиная с наименее значимого, как ноль).
Дополнительная информация:
// Loop through the first 8 characters in p
for(i = 0; i < 8; i++)
{
// Grab the least significant bit of the i'th character as an int (1 or 0)
int a = p[i] & 1;
// If it happens to be set (was a 1)
if(a)
{
// Set the corresponding (i'th) bit in c
c |= 1 << i;
}
}
Так что, если первое значение p имеет lsb, равный 1, lsb of c будет равно 1
, если второй байт в p имеетlsb = 1, второй бит c будет 1
и т. д.
. В результате каждый бит C будет принимать значение младшего значащего бита каждого из первых 8 байтовP
Бьюсь об заклад, его можно было бы кодировать более плотно, хотя, если бы я действительно хотел попробовать, но это, вероятно, нацелено на производительность:)