web-dev-qa-db-ja.com

C ++でのcharとsigned charの違いは?

次のコードを検討してください。

#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 

つまり、intsigned intは同じ型と見なされますが、charsigned charとは見なされません。何故ですか ?

そして、charsigned charを使用してmake_signedに変換できる場合、その逆の方法(signed charcharに変換する)は?

28
Vincent

これは仕様によるものです。 C++標準 は、charsigned charunsigned charは異なる型であると述べています。変換には静的キャストを使用できると思います。

18
Sergi0

つの異なる基本文字タイプ:char、signed charおよびunsigned char。文字の種類は3つありますが、表記は符号付きと符号なしの2つのみです。 (plain)charは、これらの表現の1つを使用します。他の2つの文字表現はcharコンパイラによって異なりますと同等です。

符号なしタイプでは、すべてのビットが値を表します。たとえば、8ビットunsigned charは、0から255までの値を保持できます。

この規格は、符号付きの型の表現方法を定義していませんが、範囲を正の値と負の値の間で均等に分割する必要があることを指定しています。したがって、8ビットのsigned charは、-127から127までの値を保持できることが保証されています。


どのタイプを使用するかを決定する方法は?

charを使用した計算には通常問題があります。 Charはデフォルトで一部のマシンでは署名され、他のマシンでは署名されていません。したがって、算術式では(plain)charを使用しないでください。文字を保持するためだけに使用します。小さな整数が必要な場合は、signed charまたはunsigned char

19
Ankit Gupta

実際、標準では、char、signed char、unsigned charは3つの異なるタイプであると明確に規定しています。 charは通常8ビットですが、これは標準では規定されていません。 8ビットの数値は256の一意の値をエンコードできます。違いは、これらの256個の一意の値の解釈方法のみです。 8ビット値を符号付きバイナリ値と見なすと、-128(コード化された80H)〜+127の整数値を表すことができます。符号なしと見なすと、0〜255の値を表すことができます。C++標準では、符号付き文字は-127〜127(-128ではない)の値を保持できることが保証されていますが、符号なし文字は値を保持できます。 0〜255。

Charをintに変換すると、結果は実装で定義されます!結果は、例えば単一文字 'É'(ISO 8859-1)のマシン実装に応じて-55または201になります。実際、文字(16ビット)で文字を保持しているCPUは、FFC9または00C9またはC900、あるいはC9FF(ビッグエンディアンおよびリトルエンディアンの表現)のいずれかを格納できます。 signedまたはunsigned charを使用すると、charからintへの変換結果が保証されます。

6
berhauz