2012-02-09 3 views
5

у меня был этот вопрос после прочтения этой нити Print an int in binary representation using CПонимание условия выхода из для цикла

В течение пользователей комментариев, они отправили это цикл, который назначает либо 1 или 0 в битовой позиции для того, чтобы конвертировать из int decimal в char * двоичный.

for(; bits--; u >>= 1) 
    str[bits] = u & 1 ? '1' : '0'; 

Я понимаю, почему нет необходимости в инициализированном значении. Это синтаксис для цикла, что я всегда знал:

for (variable initialization; condition; variable update) 

То, что я не понимаю, как «bit--» может быть условие выхода. Пожалуйста, помогите мне понять, как работает этот код (я тестировал его, и он действителен).

спасибо.

+1

Это то, что программисты C прокляты! Создание кода, который что-то делает, но никто его не понимает. Не пытайтесь писать такой код! бит - уменьшает битовую переменную, как только она равна нулю, возвращается false – guitarflow

+1

@guitarflow Те, кто понимают C и ее идиомы, понимают такой код как раз очень хорошо, как это очень распространено в коде C (включая книгу K & R), и я бы сказал, что эта идиома должна быть изучена, чтобы понять код С в целом. Итак, почему новый код (на любом языке) должен быть написан для тех, кто не понимает язык? Более «общепринятая» форма может даже усложнить ситуацию для читателя, свободно владеющего языком, т. Е. «Почему он не использовал [общую идиому], есть ли что-то, чего я не хватает?» – Arkku

+0

@Arkku Я также понимаю код , но вы должны согласиться, что это не хороший стиль кодирования. Написание цикла for-loop «стандартным» способом делает его более читаемым для всех, а не только для трещин. Переменные имена, такие как «u», также не являются описательным именем;) – guitarflow

ответ

8

В C значение нуля оценивается как «ложное» в булевом контексте. Поэтому, когда bits-- оценивает до 0, в контексте цикла он вычисляет значение «false» и завершает цикл.

Если вы, например, сказать:

int x = 1; 
if (--x) 
{ 
    printf("True!\n"); 
} 
else 
{ 
    printf("False!\n"); 
} 

Он будет выдавать "False", потому что --x значение 0, что "ложь" в логическом контексте.

+0

Хорошо, у меня были подозрения, что это так. Спасибо. –

+4

Чарльз, вы правы, но --x это не то же самое, что x--. Если вы измените код выше на x--, он напечатает «True!». – Diego

+0

@ dfmx123, разница между пост-инкрементом и предварительным приращением является еще одной проблемой, и это не относится к сфере действия здесь. Дело просто в том, чтобы продемонстрировать, что выражения, которые оцениваются в ноль, считаются «ложными» в условном контексте. –

1

Все условия в основном сводятся к проверке, является ли что-то 0 или нет. 0 означает false, все остальное означает true. Так что цикл будет ломаться, когда bits 0.

Вы будете иногда видеть while или if условия, написанные

if (variable) // or while(variable) 

Это просто сокращение для

if (variable != 0) // or while (variable != 0) 

Так

for (; bits--; u >>= 1) 

для

for (; bits-- != 0; u >>= 1) 
+0

Собственно, в C все считается истинным, кроме нуля, я думаю. – guitarflow

+0

@guitarflow вы правы, я исправил свой ответ –

0

bits-- - это выражение выражения типа int (так как оно вернет значение b, которое является int). Чтобы сопоставить синтаксис for loop, он преобразуется в логическое выражение, что означает, что оно истинно, если биты! = 0. На самом деле условие идентично битам! = 0, но с помощью бит - оно меняет значение битов в то же время, делая код более компактным, вот и все.

0

Как и все сказанное, в C вы можете использовать целые числа как условие - 0 или false, что-нибудь еще для true. (На самом деле, вы почти всегда делают это - даже такое выражение, как a<b это целое)

Таким образом, цикл завершится, когда bits-- будет 0.

Когда оператор -- приходит после переменной, она уменьшается переменной и получает предыдущее значение. например, если у вас есть int a=3,b; b=a--;, тогда b будет 3, а будет 2.

Итак, цикл выйдет после того, как бит будет уменьшен с 0 до -1. Это означает, что если в начале, например, bits==8, цикл будет повторяться 8 раз, тогда как в первом биты будут равны 7 (поскольку условие было проверено), а в последнем случае бит будет равен 0. Хороший способ петли через массив (так как в c массив из bits переменных индексируется от 0 до bits-1).

Смежные вопросы