c ++ 11 — Разница между char и знаковым 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)

22

Решение

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

16

Другие решения

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

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

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


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

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

13

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

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

6
По вопросам рекламы [email protected]