Почему unsigned int содержит отрицательное число

что я знаю о unsigned numerics (unsigned short, int и longs), что он содержит только положительные числа, но следующая простая программа успешно присвоила отрицательное число unsigned int:

  1 /*
  2  * =====================================================================================
  3  *
  4  *       Filename:  prog4.c
  5  *
  6  * =====================================================================================
  7  */
  8 
  9 #include <stdio.h>
 10 
 11 int main(void){
 12 
 13     int v1 =0, v2=0;
 14     unsigned int sum;
 15     
 16     v1 = 10;
 17     v2 = 20;
 18     
 19     sum = v1 - v2;
 20     
 21     printf("The subtraction of %i from %i is %i n" , v1, v2, sum);
 22     
 23     return 0;
 24 }

выход : The subtraction of 10 from 20 is -10

4 ответов


%i - спецификатор формата для подпись integer; вам нужно использовать %u для печати целого числа без знака.


С printf, the %i формат выводит a signed int. Использовать %u вывести unsigned int. Это распространенная проблема при запуске программирования C. Чтобы ответить на ваш вопрос, результат v1 - v2 - это -10, но sum это unsigned int, поэтому реальный ответ, вероятно, что-то вроде 4294967286 (232 - 10). Посмотрите, что вы получаете, когда используете The subtraction of %i from %i is %u \n. :)


Signed int и unsigned int имеют одинаковый размер в памяти, единственная разница между ними заключается в том, как вы их intepret. Подписанные значения используется представление в дополнительном коде.

Если вы поместите 0xFFFFFFFF в 4-байтовую память, а затем спросите, какое значение там? Ну, если мы интерпретируем его как signed int, то это -1, но если мы интерпретируем его как unsigned int, то значение равно 4294967295. В любом случае это один и тот же битовый шаблон, разница в том, какой смысл вы дать ему.

когда вы назначили 10-20 в unsigned int, вы рассчитали значение -10 (C не выполняет проверку переполнения или подтока), это битовый шаблон 0xFFFFFFF6, что означает -10 в signed int или 4294967286 в unsigned int. Если вы затем скажете компилятору (с помощью %i) распечатать подписанный int, то он интерпретирует этот битовый шаблон как подписанный int и печатает -10, если вы сказали компилятору (с помощью %u) распечатать неподписанный int, то он интерпретирует этот битовый шаблон как без подписи и печатает 4294967286.


потому что значение unsigned int, которое хранится в sum, рассматривается как десятичное целое число со знаком в printf %i