型変換
異なるデータ型同士の扱い方
char型やshort型などは、それぞれ記憶できる数値の幅に違いがありますが、中身は同じ整数です。
これらのデータ型は互いに変換することができます。
これを型変換といいます。
暗黙の型変換
型変換は、変換を特に指定せずに自動的に行われるものがあります。
これを暗黙の型変換(暗黙的型変換)といいます。
代入時の変換
変数への値の代入時、代入される値は自動的にその変数の型に変換されます。
小数型を整数型に代入した場合、小数点以下が切り捨てられます。
(四捨五入ではない)
double _double = 1234.56;
int _int = _double;
printf("%d", _int);
1234
以下のコードでは、char型からshort型への変換が行われます。
short型のほうが扱えるデータ量が大きいので、問題はありません。
char _char = 127;
short _short = _char;
以下のコードでは、char型のほうが小さいので、short型変数にchar型で扱える以上の数値が入っているとオーバーフローが発生します。
short _short = 1000;
char _char = _short;
細かいことを言うと、整数のリテラルはint型として扱われますから、int型以外の変数に代入するとこれも暗黙の型変換が行われます
//int型からshort型に変換
short _short = 0;
計算時の変換
暗黙の型変換は、計算時にも行われます。
char _char = 10;
short _short = 20;
long _long = 30;
long kekka = _char + _short + _long;
4行目では、まずchar型とshort型の計算が行われます。
この時の結果は、大きい方のデータ型であるshort型に合わせられます。
次はshort型とlong型との計算となり、結果は大きい方であるlong型に合わせられます。
つまり、データ型同士が異なる値の計算は、大きいデータ型の方に合わせられます。
これは整数型と小数型の場合でも同じです。
short _short = 10;
float _float = 20.0f;
double kekka = _short + _double;
short型とfloat型ではfloat型のほうが大きいので、計算結果はfloat型として扱われます。
最終的にはdouble型変数に代入していますので、double型となります。
明示的な型変換(キャスト)
型変換は自動で行われるもののほか、自分で変換を指定することもできます。
//暗黙の型変換
double kekka1 = 10 / 4;
//明示的な型変換
double kekka2 = (double)10 / 4;
最初のコードは、int型同士の計算なので結果もint型となります。
その結果、小数点以下が切り捨てられ数学的に正しい値は得られません。
二番目のコードは、片方の数値の前に「(double)」という記述があります。
このとき、この10はdouble型として扱われることになります。
これを明示的な型変換(キャスト)と言います。
丸括弧の中にデータ型名を記述したものをキャスト演算子と言います。
10がdouble型として扱われることで、double型とint型の計算となり、結果はdouble型となるため正しい計算結果を得られます。
上のコードのように数値を直接書く場合(リテラル)は、10を10.0と書けばdouble型として扱うことはできます。
しかし変数の場合はこの書き方では対処できないため、明示的な型変換が必要になります。
int _int = 10;
double kekka = (double)_int / 4;
変数_intは一時的にdouble型として扱われるだけで、変数自体のデータ型が変換されるわけではありません。
以下のように書けば計算式の結果をdouble型にキャストすることができますが、括弧内の計算の時点でその結果がint型になっているので、正しい値とはなりません。
(変数への代入時は暗黙の型変換が行われるため、無駄な記述となります)
int _int = 10;
double kekka = (double)(_int / 4);