Использование unsigned int в разных случаях?

Я хочу спросить, в чем разница между этими двумя случаями?

Случай 1:

unsigned int i;
for(i=10;i>=0;i--)
printf("%d",i);

Это приведет к бесконечному циклу!

Случай 2:

unsigned int a=-5;
printf("%d",a);

На экране будет напечатано -5.

Теперь причина для случая 1 заключается в том, что i объявлено как unsigned int, поэтому оно не может принимать отрицательные значения значения, следовательно, всегда будет больше 0.

Но в случае 2, если a не может принимать отрицательные значения, почему печатается -5???

В чем разница между этими двумя случаями?


person Mrigank    schedule 11.07.2014    source источник
comment
Вы сказали printf интерпретировать a как целое число со знаком, что оно и сделало.   -  person mafso    schedule 11.07.2014
comment
"%d".... хочешь "%u"?   -  person BLUEPIXY    schedule 11.07.2014
comment
неправильное указание аргумента для printf является неопределенным поведением.   -  person Shafik Yaghmour    schedule 11.07.2014
comment
+1, потому что у меня такие же сомнения.   -  person Jerky    schedule 11.07.2014


Ответы (3)


i объявлен без знака, поэтому он не может принимать отрицательные значения.

Это правильно. Большинство оптимизирующих компиляторов заметят это, удалят условие из цикла и выдадут предупреждение.

В случае 2, если a не может принимать отрицательные значения, почему печатается -5?

Потому что на вашей платформе int и unsigned int имеют такое представление, что присвоение -5 unsigned int, а затем передача его printf сохраняет представление -5 в форме, которая позволяет printf давать "правильный" результат.

Это верно для вашей платформы, но другие платформы могут отличаться. Вот почему стандарт считает это поведение неопределенным (т. е. printf вообще может производить любой вывод). Если вы печатаете с использованием беззнакового спецификатора формата, вы увидите большое положительное число.

person Sergey Kalinichenko    schedule 11.07.2014
comment
Могу я спросить, почему в первом случае бесконечный цикл? - person Jerky; 11.07.2014
comment
@Jerky Поскольку числа без знака не могут стать отрицательными, поэтому независимо от значения i условие i >= 0 остается верным. - person Sergey Kalinichenko; 11.07.2014
comment
Спасибо, сэр, теперь я понял! - person Mrigank; 11.07.2014

Разница в том, что вы печатаете a как целое число со знаком.

printf("%d",a);

поэтому, хотя a может быть беззнаковым, %d запрашивает печать двоичного значения как значения со знаком. Если вы хотите напечатать его как значение без знака, используйте

printf("%u",a);

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

person Soren    schedule 11.07.2014

Когда значение -ve присваивается переменной unsigned, она не может хранить это значение, и это значение добавляется к UINT_MAX, и, наконец, вы получаете положительное значение.
Обратите внимание, что использование неправильного спецификатора для вывода типа данных вызывает неопределенное поведение.
См. C11: 7.21.6 p(6):

Если спецификация преобразования недействительна, поведение не определено.282)

unsigned int a=-5;
printf("%u",a);  // use %u to print unsigned

напечатает значение UINT_MAX - 5.

person haccks    schedule 11.07.2014
comment
это UINT_MAX вместо UMAX_INT - person mch; 11.07.2014
comment
@мч; Спасибо за напоминание. - person haccks; 11.07.2014