Цикл for и цикл while для отображения одного значения (CS50)

Смотрю вторую неделю лекций CS50 (здесь: https://video.cs50.net/2016/fall/lectures/2?t=84m33s), где он повторно реализует strlen, запуская цикл while над символами строки, с этим циклом (другой код отредактирован):

string s = get_string();
int n = 0;
while (s[n] != '\0')
{
    n++;
}
printf("%i",n);

Мой вопрос: можно ли изложить вышеизложенное в цикле for?

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

Мне любопытно, может ли цикл for добиться того же «одноразового, условного» вывода в таком случае, как этот. Если я правильно помню, while уникален для C lang, а другие, такие как Python, имеют исключительно циклы for (скажите мне, если я ошибаюсь!).


person zangiku    schedule 27.04.2017    source источник
comment
скажи мне, если я ошибаюсь!, ты очень ошибаешься   -  person Netwave    schedule 27.04.2017
comment
while уникален для C lang. Я не знаю, откуда вы это взяли. Часто встречаются циклы while в Python. Вы ищете ответ Python или ответ C, поскольку я не понимаю, почему это было помечено Python, помимо утверждения этого ошибочного предположения?   -  person roganjosh    schedule 27.04.2017
comment
Действительно ошибочно! Должно быть, мои петли пересеклись ????   -  person zangiku    schedule 27.04.2017
comment
Правильный путь: for(size_t n=0; s[n] != '\0'; n++) {}. Или вы можете сделать это небрежными, устаревшими способами.   -  person Lundin    schedule 27.04.2017


Ответы (2)


То же самое можно написать с помощью цикла for. Например

string s = get_string();
int n = 0;
for ( ; s[n] != '\0'; n++ );
printf("%i",n);

Однако этот цикл for с пустым подоператором может запутать читателя кода, даже если он написан примерно так:

for ( ; s[n] != '\0'; n++ ) /* empty body */;

or

for ( ; s[n] != '\0'; n++ ) { / *empty body */ }

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

Учтите, что правильнее было бы использовать тип size_t вместо типа int для переменной n.

Например

string s = get_string();
size_t n = 0;
for ( ; s[n] != '\0'; n++ );
printf("%zu",n);
person Vlad from Moscow    schedule 27.04.2017
comment
Вот почему многие люди используют {} вместо ;, чтобы было понятнее, что тело цикла пусто. - person ; 27.04.2017
comment
@InternetAussie Вы можете использовать только комментарий перед ;. Однако в любом случае такой код сбивает читателей с толку. - person Vlad from Moscow; 27.04.2017
comment
Пожалуйста, позвольте мне уточнить - цикл while дает вам один вывод - если строка charles, цикл while выведет 6, но цикл for (используя int - я еще не понимаю size_t) выведет 0123456, нет ? - person zangiku; 27.04.2017
comment
@kadomatsu Выходной оператор — это следующий оператор после цикла for. Таким образом, он будет выполнен после завершения цикла for. Цикл for имеет пустое подоператор, то есть цикл for не будет выполнять ничего, кроме выражений, указанных непосредственно в нем. - person Vlad from Moscow; 27.04.2017
comment
Также, @VladfromMoscow, раз уж мы здесь, в чем причина size_t вместо int? - person zangiku; 27.04.2017
comment
@kadomatsu Тип размера любого объекта, возвращаемого оператором sizeof, — size_t. Тип int не может хранить значение размера большого объекта. - person Vlad from Moscow; 27.04.2017
comment
@VladfromMoscow Наконец-то я понял - printf запускается после цикла, где n уже увеличилось. Спасибо! - person zangiku; 28.04.2017
comment
@kadomatsu C имеет так называемый нулевой оператор. Например ;;; . Есть три нулевых утверждения. Из стандарта C оператор 3Anull (состоящий только из точки с запятой) не выполняет никаких операций. Таким образом, оператор for, показанный в ответе, имеет нулевое подоператор. Вызов printf выполняется после цикла. - person Vlad from Moscow; 28.04.2017

Этот код также будет работать в этом случае:

int n=0;
for(;s[n];n++);
printf("%d ",n);

как это работает:

Строковые элементы имеют значения ASCII, поэтому, пока в строке есть символы, часть условия цикла for выполняется. Когда он достигает конца строки, т.е. '\0' (целочисленное значение '\0' равно нулю), условие не выполняется, цикл завершается.

person anil    schedule 27.04.2017