Почему в unsigned int содержится отрицательное число - PullRequest
8 голосов
/ 11 мая 2010

Что я знаю о беззнаковых числах (unsigned short, int и longs), что он содержит только положительные числа, но следующая простая программа успешно присвоила отрицательное число беззнаковому 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 ]

22 голосов
/ 11 мая 2010

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

8 голосов
/ 11 мая 2010

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

6 голосов
/ 12 мая 2010

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

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

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

1 голос
/ 11 мая 2010

Поскольку значение без знака int, которое хранится в сумме, обрабатывается как десятичное целое число со знаком в printf% i

...