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

В C/С++ почему делает while (выражение); нужна полутень?

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

Итак, что это значит...

do
{
  some stuff
}
while(test);

more stuff

что лучше, чем...

do
{
  some stuff
}
while(test)

more stuff
4b9b3361

Ответ 1

Это потому, что в то время как утверждения действительны в цикле do-while.

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

int x = 10;
int y = 10;

do 
  while(x > 0)
    x--;
while(x = y--);

Ответ 2

Потому что вы заканчиваете утверждение. Оператор заканчивается либо блоком (ограниченным фигурной скобкой), либо точкой с запятой. "делайте это, пока это" - это единственный оператор и не может закончиться блоком (потому что он заканчивается "while" ), поэтому ему нужна точка с запятой точно так же, как и любое другое утверждение.

Ответ 3

Если вы посмотрите на грамматику С++, вы увидите, что итерационные выражения определяются как

while ( условие )

для оператора < для оператора

do оператор while ( выражение );

Обратите внимание, что только оператор do-while имеет ; в конце. Итак, вопрос в том, почему do-while настолько отличается от остальных, что ему нужен дополнительный ;.

Давайте поближе рассмотрим: как for, так и regular while завершаем оператор. Но do-while заканчивается управляющим выражением, заключенным в (). Наличие этого приложения () уже позволяет компилятору однозначно найти конец управляющего выражения: внешнее закрытие ) обозначает, где заканчивается выражение, и, следовательно, где заканчивается весь оператор do-while. Другими словами, завершение ; действительно избыточно.

Однако на практике это означало бы, например, следующий код

do
{
  /* whatever */
} while (i + 2) * j > 0;

если он действителен с точки зрения грамматики, действительно будет проанализирован как

do
{
  /* whatever */
} while (i + 2)

*j > 0;

Это формально звучит, но на самом деле это не интуитивно. Я предполагаю, что по таким причинам было принято решение добавить более явный терминатор в оператор do-while - точку с запятой. Разумеется, в ответе @Joe White есть также соображения простой и простой последовательности: все обычные (не-составные) операторы в C заканчиваются на ;.

Ответ 4

Пока я не знаю ответа, последовательность кажется лучшим аргументом. Каждая группа операторов в C/С++ либо заканчивается

  • Точка с запятой
  • Скобка

Зачем создавать конструкцию, которая не выполняет никаких операций?

Ответ 5

Согласование согласования потока

Учитывая согласованность...

if (expr) statement;
do statement; while (expr);
for (expr; expr; expr) statement;
while (expr) statement;

... все эти конструкции управления потоком заканчиваются точкой с запятой.

Но, противодействуя тому, что мы можем отметить, что из форм блока-оператора, только do while разделяется точкой с запятой:

if (expr) { ... }
do { ... } while (expr);
for (expr; expr; expr) { }
while (expr) { }

Итак, у нас есть ';' или '}', но никогда не "голый" ).

Согласованность разделителей инструкций

Мы можем, по крайней мере, сказать, что каждое утверждение должно быть разделено на ; или } и визуально, что помогает нам отличать утверждения.

Если точка с запятой не требуется, рассмотрите:

do statement1; while (expr1) statement2; do ; while (expr2) statement3; while (expr3) statement4;

Очень сложно визуально разрешить это для отдельных операторов:

do statement1; while (expr1)
statement2;
do ; while (expr2)
statement3;
while (expr3) statement4;

В отличие от этого, более простое решение, как ;, сразу после условия while говорит вам искать назад для do и что следующий оператор не связан с этим while:

do statement1; while (expr1); statement2; do ; while (expr2); statement3; while (expr3) statement4;

Имеет ли значение, учитывая, что люди отступают от своего кода, чтобы сделать поток понятным? Да, потому что:

  • люди иногда совершают ошибки (или временно переносят их по мере массирования кода), и если это визуально выделяется, что означает, что оно будет исправлено легче, а
  • макроподстановки могут сбрасывать множество операторов в одной строке, и нам иногда нужно визуально проверять вывод препроцессора при устранении неполадок или выполнении QA.

Последствия использования препроцессора

Также стоит отметить знаменитый препроцессор do-while idiom:

#define F(X) do { fn(X); } while (false)

Это можно заменить следующим образом:

if (expr)
    F(x);
else
    x = 10;

... дает...

if (expr)
    do ( fn(x); } while (false);
else
    x = 10;

Если точка с запятой не была частью оператора do while, то оператор if будет интерпретироваться как:

if (expr)
    do-while-statement
; // empty statement
else
    x = 10;

... и потому, что после if есть два утверждения, они считаются завершенными, что делает оператор else непревзойденным.

Ответ 6

C заканчивается точкой с запятой (тогда как Pascal разделяется точкой с запятой). Было бы непоследовательно отбрасывать точку с запятой.

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

Ответ 7

В прообразах C/С++ не вносят вклад в структуру (например, в python). В операциях C/С++ must завершается точкой с запятой. Это разрешено:

do
{
  some stuff; more stuff; even more stuff;
}
while(test);

Ответ 8

Мой ответ заключается в том, что компилятор может запутаться, когда мы не включили точку с запятой в завершение цикла do.....while();. Без этого неясно:

  • когда дело заканчивается?
  • Если это может быть отдельный цикл, который следует сразу после цикла do.

Вот почему мы включаем точку с запятой в конце цикла do......while, чтобы указать, что цикл завершается здесь, если условие ложно.