Ни одна из версий не является хорошим кодированием; оба игнорируют возможность достижения EOF перед чтением пробела, и оба игнорируют возможность переполнения буфера перед чтением пробела.
Во-первых, правильно. Содержит назначение:
x[num++] = getchar()
Результатом присваивания является присвоенное значение. Таким образом, если getchar()
возвращает «X», результатом присваивания будет «X». Затем результат присваивания сравнивается с пробелом; они разные, и петля повторяется. Если getchar()
возвращает пробел, то результатом присваивания также является пробел, и пробел равняется пробелу, поэтому цикл завершается.
Второй явно неисправен. Поскольку присваивание имеет более низкий приоритет, чем !=
, в результате код выглядит так:
while (x[num++] = (getchar() != ' '))
;
То есть символ читается getchar()
и сравнивается с пробелом, генерируя значение 1, если символ не пустой, и 0, если это пустой. Это 0 или 1 присваивается x[num++]
, а затем оценивается как логическое условие. Если результат был 0, цикл завершается; если результат был 1, цикл продолжается. Обратите внимание, что прочитанные символы не записываются в этой версии - именно поэтому компилятор выдает предупреждение. Это почти всегда ошибка; в тех странных случаях, когда это не является ошибкой, вы можете сказать компилятору, что, предоставив дополнительные скобки, чтобы сделать ваше намерение кристально ясным для компилятора и для вашей человеческой аудитории, других людей, которые будут читать ваш код. (Помните: если вы вернетесь через 6 месяцев или даже через 6 недель, вы будете другим человеком, и у вас могут возникнуть трудности с запоминанием таких тонкостей. Объясните это всем. Необходимо установить тонкий баланс между чрезмерными скобками и код в скобках.)
Код, вероятно, должен читать:
int c;
int max = sizeof(x) - 1;
int num = 0;
while ((c = getchar()) != EOF && num < max && (x[num++] = c) != ' ')
;
Обратите внимание, в частности, что c
должно быть int
, а не char
.