Подтвердить что ты не робот

Использует блок while, чтобы ничего не делать плохо?

В настоящее время я работаю над упражнениями на "языке программирования C". Вот одно из моих решений:

int c;

while ((c=getchar()) != EOF) {

if (c == ' ') {

    while ((c = getchar()) == ' ')

    {}  // do nothing?

    putchar(' ');

}

putchar(c);

}

Я нашел несколько решений здесь, которые сильно отличаются от моих и используют дополнительную переменную, чтобы отслеживать, что происходит, тогда как я просто использую цикл while, чтобы пропустить все пробелы. Мое решение кажется немного беспорядочным, так как кажется немного хакерским, чтобы иметь петлю while, между которой нет фигурных фигурных скобок. Мне было интересно, есть ли веские причины не делать этого? Спасибо за любой совет:-)

4b9b3361

Ответ 1

Совсем нет. Я считаю, что в K & R вы обнаружите, что в K & R вы ничего не делаете так, как это делается.

Это вопрос личных предпочтений, но я предпочитаю, чтобы мои строки do-nothing выглядели следующим образом:

while(something());

Другие предпочитают точку с запятой идти по отдельной строке, чтобы укрепить тот факт, что она представляет собой цикл:

while(something())
  ;

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

while(something())
{
}

Все это действует - вам просто нужно выбрать стиль, который вам нравится, и придерживаться его.

Ответ 2

Ваш вопрос: "Использует ли блок времени ничего плохого?" также можно ответить в терминах потери циклов ЦП. В этом случае ответ "Нет", так как процесс будет спать, пока он ждет ввода пользователем символа.

Процесс просыпается только после ввода символа. Затем тест будет происходить, и если тест пройдет, то есть c == '', процесс снова перейдет в спящий режим, пока не будет введен следующий символ. Это повторяется до тех пор, пока не будет введен символ без пробела.

Ответ 3

Я думаю, что это вполне приемлемо.

Я бы либо написал:

//skip all spaces
while ((c = getchar()) == ' ') {} 

чтобы было очевидно, что эта одна строка кода делает одно.

Или я бы написал его вот так:

while ((c = getchar()) == ' ') {
    //no processing required for spaces
}

чтобы он соответствовал остальной части вашего кода.

Лично я не поклонник

while ((c = getchar()) == ' ');

формат. Я думаю, что легко пропустить полуточку.

Ответ 4

Ну, если вам действительно не нравятся пустые фигурные скобки, вы можете реорганизовать этот внутренний цикл в

while (c == ' ') {c = getchar();}

Это требует дополнительного сравнения, так что цикл while будет лучше.

Ответ 5

Я не думаю, что процедура есть, но ваше форматирование довольно странно. Нет ничего плохого в:

/* Eat spaces */
while ((c = getchar()) == ' ');

(то есть указать намеренно не тело)

Ответ 6

Я бы предпочел:

while ((c = getchar()) == ' ') /* Eat spaces */;

У меня также была известна процедура, называемая DoNothing, специально для вызова в таких случаях. Это дает понять, что вы действительно ничего не хотите делать.

В то время как несуществующие тела петли совершенно приемлемы, должно быть ОЧЕНЬ ясно, что это намеренно.

Ответ 7

A while, который ничего не делает, это плохо:

while(!ready) {
   /* Wait for some other thread to set ready */
}

... - действительно, действительно, дорогой способ подождать - он будет использовать столько же CPU, сколько ОС даст, до тех пор, пока ready будет ложным, крадя процессорное время, с которым другой поток может делать полезную работу.

Однако ваш цикл не ничего не делает:

while ((c = getchar()) == ' ')
    {};  // skip

... потому что он вызывает getchar() на каждой итерации. Следовательно, как согласились все остальные, все, что вы сделали, прекрасно.

Ответ 8

Я использовал такой код. Я не думаю, что есть какая-то причина не использовать его, если ситуация оправдывает это.

Ответ 9

Я думаю, в этом нет проблем. Вы можете использовать его, во многих ситуациях я предпочитаю его.

Ответ 10

Канонический путь, используемый с незапамятных времен, имеет вид, например, в книге Лиона - это

while(condition)       // Here the whole thing
    ;                  // empty body.

Фактически, в общем случае для оператора null используется соглашение "полуколор на отдельной строке". Например, вы, например, смотрите

if( condition-1)
     ;
else if (condition-2)
     stmt;
else {
     // do stuff here
}

Это намного более необычно, но появляется либо там, где условие-1 очень сложно, поэтому вы не хотите отрицать его и случайную путаницу, или когда код был оптимизирован вручную за один дюйм своей жизни, так что сначала вы хотите получить наиболее распространенный случай.

while(condition) ;
Форма

должна быть рабски предотвращена, потому что это обычная и раздражающая опечатка: вы должны четко указать, что вы сделали это нарочно. Пустые фигурные скобки

 while(condition){
 }

или его варианты, также являются проблемой, потому что они либо недостаточно выделяются, либо хуже приводят к другим опечаткам.

Ответ 11

Ну, не совсем, но это зависит от вашей архитектуры.

if (dosomething()) { ; }

Вышеупомянутое будет постоянно толкаться и выскакивать из вашего локального стека, у которого есть накладные расходы на память. Кроме того, вы также будете промывать конвейеры ваших процессоров операциями noop.

Ответ 12

Альтернативный вариант, который еще не упоминался:

while(condition)
    (void)0;

Я действительно не предпочитаю писать мои циклы таким образом, но у меня был последний семестр TA, который сделал.