2013-05-12 3 views
16

Рассмотрим следующий код:Разница между символом и символом char в C++?

#include <iostream> 
#include <type_traits> 

int main(int argc, char* argv[]) 
{ 
    std::cout<<"std::is_same<int, int>::value = "<<std::is_same<int, int>::value<<std::endl; 
    std::cout<<"std::is_same<int, signed int>::value = "<<std::is_same<int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<int, unsigned int>::value = "<<std::is_same<int, unsigned int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, int>::value = "<<std::is_same<signed int, int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, signed int>::value = "<<std::is_same<signed int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<signed int, unsigned int>::value = "<<std::is_same<signed int, unsigned int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, int>::value = "<<std::is_same<unsigned int, int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, signed int>::value = "<<std::is_same<unsigned int, signed int>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned int, unsigned int>::value = "<<std::is_same<unsigned int, unsigned int>::value<<std::endl; 
    std::cout<<"----"<<std::endl; 
    std::cout<<"std::is_same<char, char>::value = "<<std::is_same<char, char>::value<<std::endl; 
    std::cout<<"std::is_same<char, signed char>::value = "<<std::is_same<char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<char, unsigned char>::value = "<<std::is_same<char, unsigned char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, char>::value = "<<std::is_same<signed char, char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, signed char>::value = "<<std::is_same<signed char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<signed char, unsigned char>::value = "<<std::is_same<signed char, unsigned char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, char>::value = "<<std::is_same<unsigned char, char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, signed char>::value = "<<std::is_same<unsigned char, signed char>::value<<std::endl; 
    std::cout<<"std::is_same<unsigned char, unsigned char>::value = "<<std::is_same<unsigned char, unsigned char>::value<<std::endl; 
    return 0; 
} 

Результат:

std::is_same<int, int>::value = 1 
std::is_same<int, signed int>::value = 1 
std::is_same<int, unsigned int>::value = 0 
std::is_same<signed int, int>::value = 1 
std::is_same<signed int, signed int>::value = 1 
std::is_same<signed int, unsigned int>::value = 0 
std::is_same<unsigned int, int>::value = 0 
std::is_same<unsigned int, signed int>::value = 0 
std::is_same<unsigned int, unsigned int>::value = 1 
---- 
std::is_same<char, char>::value = 1 
std::is_same<char, signed char>::value = 0 
std::is_same<char, unsigned char>::value = 0 
std::is_same<signed char, char>::value = 0 
std::is_same<signed char, signed char>::value = 1 
std::is_same<signed char, unsigned char>::value = 0 
std::is_same<unsigned char, char>::value = 0 
std::is_same<unsigned char, signed char>::value = 0 
std::is_same<unsigned char, unsigned char>::value = 1 

Это означает, что int и signed int считаются того же типа, но не char и signed char. Почему это ?

И если я могу преобразование char в signed char используя make_signed, как сделать обратное (преобразование signed char к char)?

+0

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

+0

Возможный дубликат [char! = (Подписанный символ), char! = (Unsigned char)] (https://stackoverflow.com/questions/436513/char-signed-char-char-unsigned-char) – jtbandes

ответ

12

Это дизайн, C++ standard говорит, что char, signed char и unsigned char - это разные типы. Я думаю, вы можете использовать статическую трансляцию для преобразования.

5

Действительно, в стандарте точно указано, что char, signed char и unsigned char - это 3 разных типа. Символ обычно 8 бит, но этот стандарт не налагается. 8-разрядное число может кодировать 256 уникальных значений; разница заключается только в том, как интерпретируются эти 256 уникальных значений. Если вы считаете 8-битное значение в качестве знакового двоичного значения, оно может представлять целочисленные значения от -128 (все 1) до +127. Если вы считаете его неподписанным, он может представлять значения от 0 до 255. Согласно стандарту C++ подписанный символ гарантированно сможет хранить значения от -127 до 127 (не -128!), Тогда как unsigned char может удерживать значения 0 до 255.

При преобразовании символа в int результат определяется реализацией! результат может, например, be -55 или 201 в соответствии с машинной реализацией одиночного символа 'É' (ISO 8859-1). Действительно, процессор, содержащий символ в слове (16 бит), может либо хранить FFC9, либо 00C9, либо C900, или даже C9FF (в больших и маленьких представлениях). Использование подписанного или unsigned char действительно гарантирует результат преобразования char в int.

8

Есть три различных основных типов символов: символ, подписанный символ и неподписанные символ. Хотя существует три типа символов, существует только два представления: подписанный и неподписанный. Одно из этих изображений использует равное char. Какое из двух других символьных представлений эквивалентно charзависит от компилятора.

В неподписанном типе все биты представляют значение. Например, 8-разрядный unsigned char может содержать значения от 0 до 255 включительно.

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


Так как решить, какой тип использовать?

Вычисления с использованием char, как правило, проблематичны.Char по умолчанию подписан на некоторых машинах и без знака на других. Поэтому мы не должны использовать (plain) char в арифметических выражениях. Используйте его только для хранения символов. Если вам нужно маленькое целое число, явно укажите либо , подписанный char, либо unsigned char.

+0

Я знаю это пост - давным-давно, но этот ответ идентичен абзацу в * C++ Primer *, второй главе. – pkqxdd

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