Почему эта переменная size_t i = size дает «мусорное» значение при использовании в цикле for?

c #for-loop #size-t

#c #for-цикл #size-t

Вопрос:

Я определил size как переданное значение 6, отслеживая значение «size», также создающее 6, однако, когда я использую size или даже просто 6 для инициализации i, но в цикле for значение i переходит в мусор. В данном случае я просто инициализирую значение 6 для упрощения интерпретации. Насколько я понимаю, size_t похоже на unsigned int или unsigned long int в зависимости от компилятора

 for (size_t i = 6 ; i >= 0; --i){
        printf("%lun",i);
    }
 

Комментарии:

1. Какое число без знака не соответствует условию >= 0 ?

2. Поскольку i >= 0 всегда имеет значение true, цикл никогда не завершается. И когда вы уменьшаете значение нуля без знака, оно обтекается, и вы получаете максимально возможное число типа. Возможно, вы имели в виду i > 0 вместо этого.

3. Я полагал, что —i , приведет значение i к 0 после 6 итераций цикла? однако я понимаю вашу точку зрения, она никогда не будет меньше 0 . . .

4. да, он установит значение в 0, но 0 все равно больше или равно 0

5. Рассмотрим оператор «стрелка» : for (size_t i = 6 ; i --> 0; ){ . Подсказка: --> оператора нет.

Ответ №1:

gcc -Wall -Wextra позвонил и сказал привет:

предупреждение: сравнение неподписанного выражения в ‘>= 0’ всегда верно [-Wtype-limits]

Сделайте себе одолжение и прекратите поиск ошибок, которые уже обнаружил компилятор, следуя этому совету: Какие параметры компилятора рекомендуются для начинающих изучать C?


Теперь, что происходит в этом случае, так это то, что целые числа без знака имеют четко определенный перенос. Поэтому при переходе за 0 size_t будет получено значение очень большого целого числа.

Затем вы лжете printf и говорите, что передаете a signed long , когда на самом деле передаете unsigned size_t . Строго говоря, это неопределенное поведение, и может случиться все, что угодно. Правильный спецификатор преобразования для использования %zu .

На практике в системе с 8 битами long вы можете получить вывод, такой как 18446744073709551615, но это не гарантируется, поскольку это ошибка. В любом случае это вечный цикл, который приведет к зависанию программы.

Ответ №2:

i >= 0 всегда имеет значение true, потому что i является size_t и не может попасть под 0

Таким образом, цикл не завершается, это то, что ваш компилятор принимает или нет, в зависимости от ваших параметров компиляции

Если вы уменьшите значение size_t, равное 0, это значение size_t получит максимально возможное значение для size_t .

Вместо этого вы можете использовать i> 0 или использовать for(int i = 6;i >= 0;--i) , если хотите, чтобы ваш 0 был напечатан.

PS: %zu для size_t и %d для int (или %i , %d для ввода десятичных целых чисел)

Комментарии:

1. В качестве альтернативы, ssize_t это подписанная версия size_t , хотя я не думаю, что она стандартная или переносимая.

2. Я не знал об этом, вы можете найти его в библиотеке «sys / types.h»

3. ssize_t я думаю, POSIX; использовать ptrdiff_t ? Или просто протестируйте after вместо этого.

4. мой класс ограничивает ключевые слова и типы данных, которые мы можем использовать, тем, что было описано в учебнике до этого момента. Как и для массивов, proff. мы хотим использовать size_t для формирования «хороших привычек». Хотя я не понял, почему, кроме этого, вы не будете пытаться ввести отрицательное значение для индексов. Я остановился на size_t i = SIZE; i >= 1 затем для любого кода, нацеленного на i, использовался i-1 .