Поведение, определяемое реализацией , Неопределенное поведение и CHAR_MAX < 256
Давайте разберемся:
... unsigned short maxNum
... unsigned short di
char i;
for (i = di; i <= maxNum; i += di) {
printf("%u ", i);
}
char
может быть со знаком char
или без знака char
. Предположим, что это подписанный .
unsigned short
может иметь тот же диапазон, что и unsigned
, когда оба 16-битные. Однако чаще встречается unsigned short
как 16-битный и int, unsigned
* как 32-битный.
Существуют и другие возможности, но давайте go перейдем к двум вышеупомянутым предположениям.
i = di
может быть интересно, если назначенное значение выходит за пределы диапазона char
, но 100 всегда находится в диапазоне char
, поэтому i
равно 100.
Каждый аргумент в i <= maxNum
проходит через обычные целочисленные акции , поэтому подписанный char i
сначала становится int 100
, а 16-битный maxNum
становится int 256
. Поскольку 100 < 256
истинно, вводится тело l oop. Обратите внимание, что i
никогда не ожидал бы иметь значение, равное 256, поскольку CHAR_MAX
меньше 256 - даже в следующих циклах - это объясняет видимое навсегда l oop. Но подождите, есть еще
С printf("%u ", i);
, printf()
ожидает совпадающий аргумент unsigned
. Но i
как тип с меньшим диапазоном, чем int
, повышается до int
с тем же значением как часть аргумента .... Обычно печатаются несовпадающие спецификаторы и тип неопределенное поведение за исключением: когда значение может быть представлено как знаковый, так и беззнаковый тип. Поскольку 100 - это первый раз, все в порядке.
В конце l oop i += di
похоже на i = i + di;
. Аргументы сложения с go по обычные целочисленные акции и становятся int 100
добавляются к int 100
. Эта сумма составляет 200. Пока ничего странного. Тем не менее, присвоение 200 подписанному char
закрывает 200, поскольку оно выходит за пределы допустимого диапазона. Это поведение, определяемое реализацией . Присвоенное значение могло быть 0, 1 или 2 .... Обычно значение оборачивается ("модифицируется") путем добавления / вычитания 256 до тех пор, пока не попадет в диапазон. 100 + 100-256 -> -56.
Но вторая printf("%u ", i);
пытается напечатать -56 и , что - это неопределенное поведение .
Совет: включите все предупреждения, хорошие компиляторы укажут на многие из этих проблем и сэкономят ваше время.