Является ли код "while (условие);"действительный и что это значит? - PullRequest
26 голосов
/ 08 ноября 2010

Можем ли мы поставить точку с запятой как while(condition); в программировании на C?Если while(condition); действительно, что это значит?

Ответы [ 16 ]

52 голосов
/ 08 ноября 2010
while (condition);

совпадает с

while (condition) 
{
}

Может использоваться для циклов ожидания, например:

while (!isLightGreen()); // waits until isLightGreen() returns true
go();
27 голосов
/ 08 ноября 2010

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

Например, этот цикл может копировать байты в условии:

while ( '\0' != (*pt++ = *ps++))
            ;

Если вы используете точку с запятой, рекомендуется поместить его на отдельной строке, чтобы он выгляделменьше как ошибка.Лично я склонен использовать пустые скобки - {}, а иногда и комментарий о том, что пустой блок является преднамеренным.

Редактировать:

Во втором комментарии Том Андерсонотмечает улучшение по сравнению с одиночной точкой с запятой. Руководство по стилю Google C ++ рекомендует либо это, либо {}.

while ( '\0' != (*pt++ = *ps++))
            continue;
10 голосов
/ 08 ноября 2010

Да, вы можете. Это просто означает, что цикл while будет продолжать цикл, пока condition не станет ложным. Например:

#include<stdio.h>

int x = 10;
int func()
{
  printf("%d\n", x);
  return --x;
}

int main()
{
  while(func());
  return 0;
}

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

Edit:

Есть несколько примеров использования этого, например, копирование строки с нулевым символом в конце:

char dest[256];
char *src = "abcdefghijklmnopqrstuvwxyz";
while(*(dest++) = *(src++));
10 голосов
/ 08 ноября 2010

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

while (*p && *p++ != ' ');

Это продвинет указатель p на первый символ, являющийся пробелом.

Вы даже можете использовать оператор запятой, чтобы иметь обычные выражения внутри условия:

while (do_something(), do_something_else(), i < n);

Поскольку операторы, связанные с оператором запятой, оцениваются до самого правого оператора, в этом случае i < n, приведенное выше идентично:

do {
  do_something();
  do_something_else();
} while (i < n);
5 голосов
/ 08 ноября 2010

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

Программисты часто добавляют пробел перед точкой с запятой, т.е.

while(condition) ;

или пустые скобки:

while(condition) {}

показывать пустое тело намеренно, а не просто опечатку. Если вы читаете какой-то существующий исходный код и задаетесь вопросом, почему там есть пустой цикл, вам следует также прочитать следующие несколько строк, чтобы увидеть, должна ли точка с запятой действительно присутствовать или нет (т.е. выглядят ли следующие несколько строк как тело петля или нет?).

4 голосов
/ 08 ноября 2010

Я всегда пишу это как:

while (condition())
    continue;

Так что очевидно, что это не было ошибкой. Как уже говорили другие, это имеет смысл только тогда, когда условие () имеет побочные эффекты.

4 голосов
/ 08 ноября 2010

Да, это правильно.Это будет зацикливать условие, пока оно не станет ложным.

while ( condition() );
3 голосов
/ 08 ноября 2010

Код while(condition); является совершенно корректным кодом, хотя его использование ограничено. Я предполагаю, что condition - это переменная, а не функция & mdash; другие здесь обсуждают функционал condition.

Одно из применений while(condition); может заключаться в блокировке во время ожидания сигнала , например. SIGHUP, где обработчик сигнала изменяет переменную condition. Однако обычно это не лучший способ дождаться сигнала. Обычно в цикле используется sleep, т.е. while(condition) { sleep(1); }.

Отсутствие какого-либо sleep означает, что цикл будет непрерывно обрабатываться в промежуточный период и, вероятно, тратить циклы обработки впустую. Если процесс не управляет своими ресурсами (и даже там ...), я думаю, что это подходит только в том случае, если цикл необходимо разорвать с интервалом, меньшим, чем гранулярность доступной команды sleep (т. Е. Сон гранулируется с помощью второй, но вам нужен код после того, как просмотр выполнен с временем отклика менее секунды). При этом блокирующая труба или розетка могут быть предпочтительнее сигналов, с точки зрения производительности - хотя у меня нет никаких эмпирических данных для их резервного копирования, и я подозреваю, что производительность может значительно отличаться в зависимости от платформы.

Один может иметь condition, модифицированный параллельным потоком того же процесса, но я думаю, что следует предпочесть сделать это с помощью мьютекса или семафора (т. Е. condition может потребоваться быть больше, чем простая переменная).

Надеюсь, это полезно, или, по крайней мере, пища для размышлений!

3 голосов
/ 08 ноября 2010

Ключ к пониманию этого заключается в том, что синтаксис цикла while в «C» выглядит следующим образом:

while (condition) statement

Где оператор может быть любымдействительное утверждение "C".Ниже приведены все действительные операторы "C" :

{ statements } // a block statement that can group other statements

statement; // a single statement terminated by a ;

; // a null statement terminated by a ;

Итак, по правилам цикла while , оператор part (в вашем примере) будет выполняться (ничего не делать), пока условие равно истина .Это полезно, потому что это означает занятое ожидание, пока условие не станет 1023 * false .Не хороший способ ждать, но тем не менее полезный.Вы можете использовать эту конструкцию, например, если вы хотите подождать, пока другой поток (или обработчик сигнала) не установит переменную в какое-либо значение, прежде чем продолжить.

3 голосов
/ 08 ноября 2010

Это означает, что продолжает проверять состояние , пока оно не оценивается как false

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...