2013-11-21 4 views
7

Есть ли простой способ конвертировать между char и unsigned char, если вы не знаете настройки по умолчанию на компьютере, на котором работает ваш код? (на большинстве архитектур, char подписан по умолчанию, и, таким образом, имеет диапазон от -128 до +127. На некоторых других архитектур, таких как ARM, char беззнаковым по умолчанию и имеет диапазон от 0 до 255) Ищу для метод, чтобы выбрать правильную подпись или преобразовать между ними прозрачно, предпочтительно тот, который не включает слишком много шагов, поскольку мне нужно будет сделать это для всех элементов в массиве.Тип «char» в C++

Использование определения предварительного процессора позволит установить его в начале моего кода.
Как указано явный вид char, такой как signed char или unsigned char, так как только char является переменной между платформами.

Причина в том, что есть функции библиотеки, которые я хотел бы использовать (например, strtol), которые принимают char as an argument, но не unsigned char.

Я ищу несколько советов или, возможно, некоторые указатели в правильном направлении относительно того, что было бы эффективным способом сделать это, чтобы сделать код переносимым, поскольку я намерен запустить код на нескольких машинах с разными значениями по умолчанию настройки для char.

+3

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

+1

Добро пожаловать в StackOverflow!Обратите внимание, что вопрос о StackOverflow должен отвечать конкретными ссылками, а не мнениями - по этой причине следует избегать вопроса «должен ли я делать X» или «что такое хороший ресурс для Y». Также обратите внимание, что один вопрос должен охватывать одну конкретную проблему. – user4815162342

+0

Извините, я не хотел, чтобы меня называли спамом, если я вдруг задаю 6 вопросов. :(И я бы спросил в чате, но у меня нет репутации. –

ответ

1

C++ имеет три типа char однако только char разрешено изменять между компиляторами/архитектурами, как и другие два являются явной версией, и char подразумевается, поэтому допускаются по умолчанию signed или unsigned.

Для того, чтобы ваш код портативный самый простой, что нужно сделать, это явно использовать либо signed или unsigned char, как вам требуется их, однако для удобства чтения вы можете предпочесть переопределить char как тип вам нужно, или даже сделать свое собственное определение из char (для демонстрационных целей я буду использовать RLChar)

1-й вариант - снимите определить полукокса и переопределить

#ifdef __arm__ 
#undef char 
#define char signed char 
#endif 

2-й вариант - определить свой собственный тип обугленного использовать в коде

#ifndef RLChar 
#define RLChar signed char 
#endif 

(лично я, как правило, сделать второй)

Вы также можете создать еще один макрос, чтобы разрешить изменения между двумя:

#define CLAMP_VALUE_TO_255(v) ((v) > 255 ? 255 : ((v) < 0 ? 0 : (v))) 

, то вы можете использовать:

unsigned char clampedChar = CLAMP_VALUE_TO_255((unsigned char)pixel) 

или использовать такие роли, как (это путь, если все используемые вами компиляторы будут иметь поддержку):

signed char myChar = -100; 
unsigned char mySecondChar; 
mySecondChar = static_cast<unsigned char>(myChar); // uses a static cast 
mySecondChar = reinterpret_cast<unsigned char&>(myChar); // uses a reinterpretation cast 

так для сценария массива вы могли бы сделать

unsigned char* RLArray; 
RLArray = reinterpret_cast<unsigned char*>(originalSignedCharArray); 

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

+0

Я определял тип «byte» как «unsigned char». Я хотел бы знать, может ли переопределение «char» как «unsigned char» может вызвать у меня проблемы позже, например, в функции библиотеки s? Я просто использую стандартные библиотеки, такие как «iostream», «cmath» и «cstdlib». –

+0

вообще нет :) эффективно char - это просто псевдоним для любого из символов 'signed' или' unsigned', которые вы выбираете/выбираете компиляторы. Вот почему он может меняться на разных платформах :) – GMasucci

2

На данный момент я не чувствую никакой актуальной проблемы.

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

Кроме того, нет необходимости конвертировать между типами. Оба имеют одинаковое представление в памяти, на том же количестве бит (обычно 8). Речь идет только о вашей программе и библиотеках, которые она использует для интерпретации бит. Если вы собираетесь позвонить strtol, то ваши данные будут символьным массивом, и вы должны использовать простой char.

Если вы когда-либо использовать char хранить не символ (A, b, f ...), но фактическое значение (-1, 0, 42 ...), то вопросы диапазона. В таких случаях вы должны использовать signed char или unsigned char. Однако в этом случае для функций библиотек, которые хотят получить char *, мало что нужно.

Для этих библиотек, которые действительно хотят char * с фактическим двоичным блобом, нет никаких проблем. Создайте свой двоичный буфер с типом, который вы предпочитаете, подписали, без знака или неопределились и отправили его, возможно, с помощью броска. Он будет работать отлично.

+0

Точно правильно. Единственная проблема, которая может возникнуть, заключается в том, что вы конвертируете 'unsigned char *' в 'подписанный символ * или наоборот и имеете значения меньше 0/больше 127, AND находятся в системе, не использующей представление дополнения 2. Но вы никогда не должны сталкиваться с такой ситуацией. Если вы передаете строку в библиотечную функцию, такую ​​как 'strtol', вы не должны иметь никаких символов вне диапазона ASCII в первую очередь! –

+0

Я использую «unsigned char» для хранения значений размера байтов и выполнения модульной арифметики с ними. На данный момент моя программа принимает пользовательский ввод массива типа «char» из строки действительных шестнадцатеричных символов (например, AC24F5). Затем я использую «strtol» для считывания строки 2 символа за раз в виде шестнадцатеричного представления байта и сохранения полученного значения как типа «unsigned char». Одной из причин, по которой я хотел бы стандартизировать использование «char», является то, что я мог бы непосредственно вводить массив «unsigned char» в программу на половину размера и обходить процесс чтения и повторной записи. –

Смежные вопросы