Итерация массива назад в режиме цикла для остановки в 0 при использовании целых чисел без знака, вызывающих бесконечный цикл
У меня есть цикл, который должен идти от j до 0 (включительно). Моя переменная j
имеет тип size_t
, который обычно не указан.
Мой код:
#include<stdio.h>
#include<conio.h>
#define SIZE 100
int main(){
char str[SIZE];
size_t i=0;
size_t j;
puts("Enter any string");
scanf("%s",str);
while(str[i]!='\0'){
i++;
}
for(j=i-1;j>=0;j--){
printf("%c",str[j]);
}
getch();
return 0;
}
Я получаю бесконечный цикл. Если я удалю равенство нулю, он выводит обратную строку без первой буквы. так что проблема здесь?
Ответы
Ответ 1
size_t
- целое число без знака, и оно никогда не будет меньше 0
. Так
условие в цикле for
всегда верно:
for(j=i;j>=0;j--)
Вы можете изменить условие (немного уродливое):
for(j=i; j-- > 0;){
...
}
Обратите внимание, что в вашем состоянии вы также печатаете нулевой байт \0
, который является непечатаемым символом. (так как j
начинается со значения, равного длине строки). Вышеупомянутое условие также заботится об этом.
Также:
- вы можете использовать
strlen()
вместо того, чтобы перебирать его самостоятельно.
- Проверьте возвращаемое значение
scanf()
, если входное считывание будет успешным.
Ответ 2
for(j=i; j>0; j--) {
printf("%c", str[j-1]);
}
Будет другой вариант.
Для новичка может быть проще понять.
Но другие ответы были бы лучше.
edit: я бы сказал, что лучшим будет for(j=i; j-- > 0;)
на l3x.
уменьшая j после проверки, если оно больше 0.
Использование цикла do {} while() также будет работать.
j = i;
do {
j--;
printf("%c", str[j]);
} while (j > 0);
Ответ 3
Вы можете изменить j
с size_t
на long
, чтобы убедиться, что все данные по-прежнему подходят, и вы можете достичь значения -1
.
Другой вариант - закончить цикл for следующим выражением:
for (j = i - 1;;--j)
{
// code
if (j == 0) break;
}
как побочная заметка: ваш первый цикл while делает то же самое, что и strlen()
в string.h
.
Ответ 4
Циклы подсчета времени, как правило, немного неясны и трудно читаются. Вместо этого используйте эту альтернативу:
const size_t max = i-1; // maximum value that j can have
for(j=0; j<=max; j++)
{
... str[max-j];
}
Ответ 5
Беззнаковые целые числа будут перенесены в C. Любое целое без знака всегда равно или больше 0, в коде: uint >= 0
, всегда верно.
Вы можете использовать сравнение с SIZE_MAX, так как это самое большое значение для типа size_t. Код будет перебирать и печатать до 0, как и следовало бы, а затем переносить на SIZE_MAX, и цикл завершается. (Предполагается, что длина строки не SIZE_MAX.)
for(j=i; j < SIZE_MAX ;j--){
printf("%c",str[j]);
}
Также обратите внимание, что ваш код печатает нулевой символ. Поэтому начальный индекс должен быть j=i-1
, который хорошо работает с поведением обертывания, так как если длина строки равна 0, цикл for ничего не печатает, потому что i-1 == SIZE_MAX
.
Ответ 6
Проблема заключается в том, что j >= 0
всегда true
, потому что j
есть unsigned
.
При подсчете до нуля с помощью unsigned
я обычно использую postfix --
:
while (j-- > 0)
Ответ 7
Беззнаковое значение обтекает, поэтому, когда j == 0
и цикл j--
, j >= 0
по-прежнему верен.
Базовое и легко читаемое решение выглядит следующим образом:
void reversePrint(char str[])
{
size_t j = strlen(str);
while (j-- > 0)
printf("%c", str[j]);
}
Выведет строку в обратном порядке: olleH
.