2014-09-25 3 views
-4

наткнулись этой конкретной строке кода и у меня возникают некоторые проблемы с пониманием его:Не уверен, что эта строка кода означает C

a = ((((z * y) + 31) & ~31)/8) * abs(x); 

a, z, y и x все типа int.

Я понимаю, что ~ имеет эффект листать все 1 «S и 0» с, в данном случае, не 31 стать 0? Как вступает в игру &? Разве он не используется для логических операторов, а не для таких уравнений?

+2

Почему вы думаете, что только самые младшие бит будут перевернуты, а не более высокие, 0-бит тоже? – Deduplicator

+2

'&' побитовое "и". '&&' является короткозамкнутым логическим "и". Для получения дополнительной информации см. Любую достойную ссылку на С. –

+3

Разделите в нем детали с временными переменными. Затем пропустите этот код в отладчике, шаг за шагом. Это позволит очень легко понять, что происходит. –

ответ

3

Пройдем через код, используя простой пример. Давайте установим для примера пример x = y = z = 10;. Ваша единственная линия может быть разделена на несколько частей:

temp1 = z * y; 
temp2 = temp1 + 31; 
temp3 = temp2 & ~31; 
temp4 = temp3/8; 
a = temp4 * abs(x); 

Здесь temp1 - temp4 также типа int. Используя приведенный выше код и примеры значений, temp1 и temp2 просты для расчета:

temp1 = 10 * 10 = 100 
temp2 = 100 + 31 = 131 

Чтобы получить temp3, мы должны знать двоичную temp2, который в данном случае является 10000011. Таким образом, мы получаем:

10000011 
& 11100000 
---------- 
    10000000 = 128 in decimal 

So temp3 = 128. Отсюда, temp4 и a тривиальны:

temp4 = 128/8 = 16 
a = 16 * 10 = 160 

Для дальнейшего использования, когда вы запутались, что делает строка кода, первый разбить его, как я сделал выше, а затем использовать отладчик (например, GDB) для выполнения кода. Это поможет сделать код понятным.

1

Часть путаницы связана с тем фактом, что вы неправильно оценили ~31 в своей голове. Для простого случая 8-разрядных чисел 31 фактически является 00011111 и поэтому ~31 = 11100000 Not 00000000. Чтобы ответить на ваш вопрос об операторе &, это побитовый оператор И, так же как ~ является побитовым оператором NOT; поэтому ((z * y) + 31) & ~31 выполняет побитовую операцию И на результат (z * y) + 31 и ~31