it-swarm-ru.tech

Что такое неподписанный символ?

В C/C++ для чего используется unsigned char? Чем он отличается от обычного char?

433
Landon Kuhn

В C++ существует три разных типа символов:

  • char
  • signed char
  • unsigned char

Если вы используете типы символов для текста , используйте неквалифицированное char:

  • это тип символьных литералов, таких как 'a' или '0'.
  • это тип, который составляет строки C, такие как "abcde"

Он также работает как числовое значение, но не определено, будет ли это значение рассматриваться как подписанное или без знака. Остерегайтесь сравнения персонажей из-за неравенства - хотя, если вы ограничитесь ASCII (0-127), вы почти в безопасности.

Если вы используете типы символов как числа , используйте:

  • signed char, который дает вам как минимум диапазон от -127 до 127. (Обычно от -128 до 127)
  • unsigned char, который дает как минимум диапазон от 0 до 255.

"По крайней мере", потому что стандарт C++ дает только минимальный диапазон значений, который должен охватывать каждый числовой тип. sizeof (char) должен быть равен 1 (то есть один байт), но теоретически байт может быть, например, 32 бита. sizeof ПО-ПРЕЖНЕМУ БУДЕТ СООБЩАТЬ О ЕГО РАЗМЕРЕ КАК 1 - это означает, что вы можете иметь sizeof (char) == sizeof (long) == 1.

513
Fruny

Это зависит от реализации, так как стандарт C НЕ определяет подпись char. В зависимости от платформы, char может быть signed или unsigned, поэтому вам нужно явно запросить signed char или unsigned char, если ваша реализация зависит от этого. Просто используйте char, если вы собираетесь представлять символы из строк, так как это будет соответствовать тому, что ваша платформа помещает в строку.

Разница между signed char и unsigned char такова, как и следовало ожидать. На большинстве платформ signed char будет 8-битным номером дополнения до двух в диапазоне от -128 до 127, а unsigned char будет 8-битным целым числом без знака (от 0 до 255). Обратите внимание, что стандарт НЕ требует, чтобы типы char имели 8 битов, только то, что sizeof(char) возвращает 1. Вы можете получить количество бит в символе с помощью CHAR_BIT в limits.h. Однако сегодня существует немного платформ, где это будет что-то отличное от 8.

Есть хорошее резюме этой проблемы здесь .

Как уже упоминалось с тех пор, как я это опубликовал, лучше использовать int8_t и uint8_t, если вы действительно хотите представлять маленькие целые числа.

81
Todd Gamblin

Поскольку я чувствую, что это действительно необходимо, я просто хочу изложить некоторые правила C и C++ (они одинаковы в этом отношении). Во-первых, все биты unsigned char участвуют в определении значения любого неподписанного объекта char. Во-вторых, unsigned char явно указан без знака.

Теперь у меня была дискуссия с кем-то о том, что происходит, когда вы конвертируете значение -1 типа int в unsigned char. Он отказался от идеи, что получающийся unsigned char имеет все биты, установленные в 1, потому что он беспокоился о представлении знака. Но он не должен. Из этого правила сразу следует, что преобразование выполняет то, что предназначено:

Если новый тип является беззнаковым, значение преобразуется путем многократного сложения или вычитания на единицу больше максимального значения, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа. (6.3.1.3p2 в черновике C99)

Это математическое описание. С ++ описывает это в терминах исчисления по модулю, которое подчиняется тому же правилу. В любом случае не гарантируется то, что все биты в целом числе -1 равны единице перед преобразованием. Итак, что у нас есть, чтобы мы могли утверждать, что полученный unsigned char имеет все свои CHAR_BIT биты, обращенные в 1?

  1. Все биты участвуют в определении его значения, то есть в объекте не происходит битов заполнения.
  2. Добавление только одного раза UCHAR_MAX+1 к -1 приведет к значению в диапазоне, а именно UCHAR_MAX

На самом деле этого достаточно! Поэтому, когда вы хотите, чтобы unsigned char имел все биты один, вы делаете

unsigned char c = (unsigned char)-1;

Из этого также следует, что преобразование не является просто усечением битов более высокого порядка. Удачным событием для дополнения два является то, что это просто усечение, но это не обязательно верно для других представлений знака.

35
Johannes Schaub - litb

Как, например, использование nsigned char:

nsigned char часто используется в компьютерной графике, которая очень часто (хотя и не всегда) назначает отдельный байт для каждого компонента цвета. Обычно цвет RGB (или RGBA) представлен в виде 24 (или 32) битов, каждый из которых без знака. Поскольку значения nsigned char находятся в диапазоне [0,255], значения обычно интерпретируются как:

  • 0 означает полное отсутствие данного компонента цвета.
  • 255 означает 100% данного цветного пигмента.

Таким образом, вы получите красный RGB как (255,0,0) -> (100% красный, 0% зеленый, 0% синий).

Почему бы не использовать подписанный символ? Арифметика и сдвиг бит становится проблематичным. Как уже объяснено, диапазон знаковый символ существенно смещен на -128. Очень простой и наивный (в основном неиспользуемый) метод преобразования RGB в оттенки серого заключается в усреднении всех трех цветовых компонентов, но это приводит к проблемам, когда значения цветовых компонентов являются отрицательными. Красный (255, 0, 0) в среднем равен (85, 85, 85) при использовании без знака арифметика. Однако, если бы значения были знаковый символ s (127, -128, -128), мы бы получили (-99, -99, -99), что будет (29, 29, 29) в нашем без знака пространстве, что неверно.

24
Zachary Garrett

Если вы хотите использовать символ в качестве небольшого целого числа, самый безопасный способ сделать это - с типами int8_t и uint8_t.

12
jbleners

signed char имеет диапазон от -128 до 127; unsigned char имеет диапазон от 0 до 255.

char будет эквивалентно знаковому символу или неподписанному символу, в зависимости от компилятора, но это отдельный тип.

Если вы используете строки в стиле C, просто используйте char. Если вам нужно использовать символы для арифметики (довольно редко), укажите для подписи явно или без знака для переносимости.

5
James Hopkin

char и unsigned char не обязательно должны быть 8-битными типами на всех платформах - они гарантированно будут 8-битными или более. Некоторые платформы имеют 9-битные, 32-битные или 64-битные байты . Однако наиболее распространенные на сегодняшний день платформы (Windows, Mac, Linux x86 и т.д.) Имеют 8-битные байты.

5
bk1e

В терминах прямых значений обычный символ используется, когда известно, что значения находятся между CHAR_MIN и CHAR_MAX, в то время как беззнаковый символ обеспечивает двойной диапазон на положительном конце. Например, если CHAR_BIT равен 8, диапазон обычных char гарантированно будет только [0, 127] (поскольку он может быть подписан или не подписан), тогда как unsigned char будет [0, 255], а signed char будет [-127, 127 ].

С точки зрения того, для чего он используется, стандарты позволяют напрямую преобразовывать объекты POD (простые старые данные) в массив без знака. Это позволяет вам изучить представление и битовые структуры объекта. Та же самая гарантия безопасного типа наказания не существует для символа или подписанного символа.

4
Julienne Walker

unsigned char принимает только положительные значения .... как до 255

в то время как

signed char принимает как положительные, так и отрицательные значения .... например - 128 до + 127

4
munna

Беззнаковый символ - это (беззнаковое) байтовое значение (от 0 до 255). Вы можете думать о "char" как о "персонаже", но это действительно числовое значение. Обычный символ "char" подписан, поэтому у вас есть 128 значений, и эти значения отображаются на символы с использованием кодировки ASCII. Но в любом случае то, что вы храните в памяти, является байтовым значением.

3
Zac Gochenour

Если вам нравится использовать различные типы определенной длины и подписи, вам, вероятно, лучше использовать uint8_t, int8_t, uint16_t и т.д. Просто потому, что они делают именно то, что говорят.

2
Dark Shikari

Беззнаковый символ использует бит, зарезервированный для знака обычного символа, в качестве другого числа. Это изменяет диапазон на [0 - 255], а не на [-128 - 127].

Обычно неподписанные символы используются, когда вы не хотите знак. Это будет иметь значение при выполнении таких вещей, как смещение битов (смещение расширяет знак) и другие вещи при работе с символом как байтом, а не с использованием его в качестве числа.

2
JasonOfEarth

беззнаковый символ - сердце всех хитростей. Почти во всех компиляторах для платформы ALL неподписанный символ - это просто BYTE. Целое число без знака (обычно) 8 бит. это можно рассматривать как маленькое целое число или пакет битов.

В зависимости, как сказал кто-то еще, стандарт не определяет знак символа. Таким образом, у вас есть 3 различных типа "char": char, подписанный char, unsigned char.

2
ugasoft

Некоторый поиск в Google нашел это , где люди обсуждали это.

Беззнаковый символ - это в основном один байт. Таким образом, вы можете использовать это, если вам нужен один байт данных (например, возможно, вы захотите использовать его для включения и выключения флагов, передаваемых в функцию, как это часто делается в Windows API).

1
dbrien

char без знака принимает только положительные значения: от 0 до 255 char со знаком принимает положительные и отрицательные значения: от -128 до +127

0
NL628

цитата из книги "C программирования laugage":

Квалификатор signed или unsigned может применяться к символу или любому целому числу. числа без знака всегда положительны или равны нулю и подчиняются законам арифметики по модулю 2 ^ n, где n - количество бит в типе. Так, например, если символы состоят из 8 битов, переменные без знака имеют значения от 0 до 255, в то время как знаковые символы имеют значения от -128 до 127 (в машине дополнения до двух). Независимо от того, являются ли обычные символы со знаком или без знака, это машина -зависимые, но печатные символы всегда положительны.

0
ZhaoGang