Что происходит, когда я присваиваю отрицательное значение unsigned int?

Возможный дубликат:
подписанный беззнаковое преобразование в C - всегда ли он безопасен?

Скажем, я объявляю переменную типа unsigned int: unsigned int x = -1;

Теперь -1 в двух дополнениях (при условии 32-разрядной машины) - 0xFFFFFFFF. Теперь, когда я присвоил это значение x, присвоено ли значение 0x7FFFFFFF для x?

Если бы это было так, то printf ( "% d", x); напечатал бы десятичный эквивалент 0x7FFFFFFF, верно? Но, очевидно, этого не происходит, поскольку значение, которое печатается, равно -1. Что мне здесь не хватает?

Изменить: я знаю, что мы можем использовать спецификатор формата% u для печати значений без знака. Но это не помогает ответить на вопрос выше.

Ответ 1

Формат "%d" предназначен для (подписанных) значений int. Если вы используете его с неподписанным значением, он может печатать что-то отличное от фактического значения. Используйте "%u", чтобы увидеть фактическое значение, или %x, чтобы увидеть его в шестнадцатеричном формате.

В объявлении

unsigned int x = -1;

выражение -1 имеет тип int и имеет значение -1. Инициализатор преобразует это значение из int в unsigned int. Правила для преобразования без подписки говорят, что значение уменьшается по модулю UINT_MAX + 1, поэтому -1 будет конвертировать в UINT_MAX (что, вероятно, 0xffffffff или 4294967295, если unsigned int равно 32 бит).

Вы просто не можете назначить отрицательное значение объекту неподписанного типа. Любое такое значение будет преобразовано в неподписанный тип до его назначения, и результат всегда будет >= 0.

Ответ 2

Используйте %u вместо %d для печати неподписанных значений. Затем вы должны увидеть 0xFFFFFFFF.

Ответ 3

Что происходит, так это то, что сначала вы преобразовываете значение в unsigned int, присваивая 0xffffffff x. Затем, используя printf ( "% d\n" ), вы преобразуете значение обратно в подписанное значение int, сохраняя значение 0xffffffff. Таким образом, печать -1.