Разъяснения по поводу беззнакового типа в C - PullRequest
4 голосов
/ 24 марта 2020

Привет, я сейчас учусь C и есть кое-что, чего я совершенно не понимаю. Прежде всего мне сказали, что если бы я сделал это:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

Это вывело бы 255, согласно этой таблице:

table

Но я получаю странный результат: c2 = 4294967295

Теперь, что более странно, что это работает:

unsigned char c2 = -1;
printf("c2 = %d\n", c2);

Но я не понимаю, потому что char хорошо , char почему он вообще что-то печатает? Поскольку здесь указывается %d, а не %u, как это должно быть для неподписанных типов.

Ответы [ 3 ]

2 голосов
/ 24 марта 2020

Следующий код:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

Никогда не печатает 255. Таблица, на которую вы смотрите, ссылается на целое число без знака из 8 битов. Значение int в C должно составлять не менее 16 бит, чтобы соответствовать стандарту C (UINT_MAX, определенному как 2 ^ 16-1 в пункте §5.2.4.2.1, стр. 22 * ​​1007 * здесь ). Поэтому значение, которое вы увидите, будет гораздо большим, чем 255. В наиболее распространенных реализациях для int используется 32 бита, и в этом случае вы увидите 4294967295 (2 ^ 32 - 1).

Вы можете проверить, сколько битов используется для любой переменной в вашей системе, выполнив sizeof(type_or_variable) * CHAR_BIT (CHAR_BIT определено в limits.h и представляет количество бит на байт, что опять-таки большую часть времени 8).

Правильный код для получения 255 в качестве вывода:

unsigned char c = -1;
printf("c = %hhu\n", c);

Где указатель префикса hh означает (от man 3 printf) :

чч : следующее целочисленное преобразование соответствует аргументу signed char или unsigned char, или следующее преобразование n соответствует указателю на signed char аргумент.

Все остальное - это просто реализация, определенная или даже хуже undefined поведение.

1 голос
/ 24 марта 2020

В этом объявлении

unsigned char c2 = -1;

внутреннее представление -1 усекается до одного байта и интерпретируется как беззнаковый символ. То есть все биты объекта с2 установлены.

В этом вызове

printf("c2 = %d\n", c2);

аргумент, имеющий тип unsigned char, переводится в тип int, сохраняя его значение 255. Это значение выводится как целое число.

Является ли это объявление

unsigned int c2 = -1;

усечением нет. Целочисленное значение -1, которое обычно занимает 4 байта (в соответствии с размером типа int), интерпретируется как значение без знака со всеми установленными битами.

Таким образом, в этом вызове

printf("c2 = %u\n", c2);

выводится максимальное значение типа unsigned int. Это максимальное значение, потому что все биты во внутреннем представлении установлены. Преобразование из целочисленного типа со знаком в целочисленный тип без знака сохраняет знак, распространяющий его по ширине целочисленного объекта без знака.

0 голосов
/ 24 марта 2020

В C целое число может иметь несколько представлений, поэтому несколько размеров хранилищ и диапазонов значений см. В таблице ниже для получения дополнительной информации.

enter image description here

...