K & R - Упражнение 1-9 - Удаление пространств

Недавно я начал изучать C, используя книгу K & R (2-е изд.), и у меня просто возникают проблемы, связанные с этим решением, для упражнений 1-9, которые:

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

Я нашел следующее решение в Интернете, и это в основном имеет смысл, за исключением того, что эта точка с запятой выше putchar ('');. Без него программа не выполняет свою функцию должным образом, какую функцию выполняет эта полуколония?

#include <stdio.h>

int main(void)
{
  int c;

  while ((c = getchar()) != EOF) {
    if(c  == ' ') {
      while((c = getchar()) == ' ')
      ;
      putchar(' ');
    }
    putchar(c);
  }
}

Спасибо заранее.

Ответ 1

Заявление:

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

имеет неправильный отступ. Он должен гласить:

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

; - пустой оператор, эквивалентный пустующему блоку { }.

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

while ((c = getchar()) == ' ') {
    /* nothing */
}

while ((c = getchar()) == ' ')
    /* nothing */;

Некоторые смелые программисты записывают эту еще более запутанную форму (избегайте ее):

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

Я лично предпочитаю эту эквивалентную форму:

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

Ответ 2

Утверждение

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

анализируется как

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

который имеет тот же эффект, что и

while((c = getchar()) == ' ') {
     /* Do nothing */
}

Другими словами, это цикл while, тело которого не имеет эффекта. Акт проверки состояния цикла while считывает символы и удаляет пробелы, что вы хотите сделать.

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