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

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

16 ответов

Решение

В 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,

Это зависит от реализации, так как стандарт C НЕ определяет подпись 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 если вы действительно хотите представить маленькие целые числа.

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

Теперь у меня была дискуссия с кем-то о том, что происходит, когда вы конвертируете значение -1 типа int to 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;

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

Как например использование неподписанного символа:

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

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

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

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

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

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

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

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

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

в то время как

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

signed char а также unsigned char оба представляют 1 байт, но имеют разные диапазоны.

   Type        |      range
-------------------------------
signed char    |  -128 to +127
unsigned char  |     0 to 255

В signed char если мы рассмотрим char letter = 'A', 'A' представляет двоичное число 65 в ASCII/Unicode, Если можно сохранить 65, можно также сохранить -65. Нет отрицательных двоичных значений вASCII/Unicode нет необходимости беспокоиться об отрицательных значениях.

пример

#include <stdio.h>

int main()
{
    signed char char1 = 255;
    signed char char2 = -128;
    unsigned char char3 = 255;
    unsigned char char4 = -128;

    printf("Signed char(255) : %d\n",char1);
    printf("Unsigned char(255) : %d\n",char3);

    printf("\nSigned char(-128) : %d\n",char2);
    printf("Unsigned char(-128) : %d\n",char4);

    return 0;
}

Выход -:

Signed char(255) : -1
Unsigned char(255) : 255

Signed char(-128) : -128
Unsigned char(-128) : 128

числа без знака always positive or zeroи подчиняться laws of arithmetic modulo 2^n, где n количество бит в типе

пример: если символы 8 битов, unsigned char переменные имеют значения между 0 and 255, в то время как signed chars иметь значения между -128 and 127.

Другие вопросы по тегам