В чем разница между подписанным и unsigned int?
В чем разница между подписанным и unsigned int
Ответ 1
Как вы, вероятно, знаете, int
хранится внутри двоичного кода. Обычно int
содержит 32 бита, но в некоторых средах может содержать 16 или 64 бита (или даже другое число, обычно, но не обязательно, по два).
Но для этого примера рассмотрим 4-битные целые числа. Крошечный, но полезный для иллюстрации.
Так как в таком целом есть четыре бита, он может принимать одно из 16 значений; 16 - от двух до четвертой, или 2 раза 2 раза 2 раза 2. Каковы эти значения? Ответ зависит от того, является ли это целое число signed int
или unsigned int
. При значении unsigned int
значение никогда не будет отрицательным; нет знака, связанного со значением. Вот 16 возможных значений четырехразрядного unsigned int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
... и вот 16 возможных значений четырехбитового signed int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
Как вы можете видеть, для signed int
наиболее значимый бит - 1
тогда и только тогда, когда число отрицательно. Поэтому для signed int
s этот бит известен как "знаковый бит".
Ответ 2
Иногда мы заранее знаем, что значение, хранящееся в заданной целочисленной переменной, всегда будет положительным - когда оно используется, например, только для подсчета. В таком случае мы можем объявить переменную без знака, как в, unsigned int num student;
. При таком объявлении диапазон допустимых целочисленных значений (для 32-разрядного компилятора) будет смещаться от диапазона от -2147483648 до +2147483647 до диапазона от 0 до 4294967295. Таким образом, объявление целого числа без знака почти удваивает размер максимально возможного значение, которое оно в противном случае может иметь.
Ответ 3
В терминах простых людей unsigned int является целым числом, которое не может быть отрицательным и, следовательно, имеет более высокий диапазон положительных значений, которые он может принять. Подписанный int является целым числом, которое может быть отрицательным, но имеет более низкий положительный диапазон в обмен на более отрицательные значения, которые он может принять.
Ответ 4
int
и unsigned int
- два различных целочисленных типа. (int
также можно назвать signed int
или просто signed
; unsigned int
также можно назвать unsigned
.)
Как следует из названий, int
- это целочисленный тип со знаком, а unsigned int
- целочисленный тип без знака. Это означает, что int
может представлять отрицательные значения, а unsigned int
может представлять только неотрицательные значения.
Язык C задает некоторые требования к диапазонам этих типов. Диапазон int
должен быть не менее -32767
.. +32767
, а диапазон unsigned int
должен быть не менее 0
.. 65535
. Это означает, что оба типа должны быть не менее 16 бит. Они 32 бита на многих системах или даже 64 бита на некоторых. int
обычно имеет дополнительное отрицательное значение из-за представления двух дополнений, используемых большинством современных систем.
Возможно, самым важным отличием является поведение подписанной или беззнаковой арифметики. Для подписанного int
переполнение имеет поведение undefined. Для unsigned int
переполнения нет; любая операция, которая дает значение за пределами диапазона типа, обертывается вокруг, например, UINT_MAX + 1 == 0
.
Любой целочисленный тип, как подписанный, так и unsigned, моделирует поддиапазон бесконечного множества математических целых чисел. Пока вы работаете со значениями в пределах диапазона типа, все работает. Когда вы приближаетесь к нижней или верхней границе типа, вы сталкиваетесь с разрывом, и вы можете получить неожиданные результаты. Для знаковых целых типов проблемы возникают только для очень больших отрицательных и положительных значений, превышающих INT_MIN
и INT_MAX
. Для неподписанных целых типов проблемы возникают при очень больших положительных значениях и в нуле. Это может быть источником ошибок. Например, это бесконечный цикл:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
потому что i
всегда больше или равно нулю; что характер неподписанных типов. (Внутри цикла, когда i
равно нулю, i--
устанавливает его значение в UINT_MAX
.)