Използване на 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
@mch; Благодаря, че ми напомни. - person haccks; 11.07.2014