Итерация массива назад в режиме цикла для остановки в 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.