こんにちは、めのんです!
今回はデータ型の変換について見ていきます。
暗黙な型変換
C++では、整数型や浮動小数点型はとくに何もしなくても暗黙的に型変換されます。
たとえば、次のようにint型の変数iを使ってunsigned int型の変数uを初期化しようとすると、iの値「-123」をunsigned int型に変換した上でuの初期値に使うことになります。
ところが、uの型はunsigned int型ですからマイナスの値を表現することができません。
こういう場合は-123にunsigned int型の最大値(典型的には4,294,967,295)+1を加えた値になります。
つまりうんと大きな数になってしまいます。
こういうこともあって、先ほどのコードをコンパイルしようとするとコンパイラによっては警告が出ます。
うんと大きな数になってしまうのが期待通りならいいんですが、そうでなければ大変なことになってしまうのでコンパイラが教えてくれるんですね。
明示的な型変換
警告はあってもコンパイルはできますし、もちろんできあがったプログラムを実行することもできます。
ですが、このような警告がたくさん出ると大事なメッセージが埋もれてしまうこともありますし、警告を見たほかの方が問題があるのかないのかすぐにはわからないことことがあります。
static_cast
そこで、明示的に型変換をしてあげれば意図が明確になりますので警告も出なくなります。
明示的な型変換には「static_cast」というキーワードを使います。
このように、static_castに続けて変換したい型名を山形括弧(< >)で囲みます。
そして、そのあとに変換元の式(ここではi)を丸括弧で続けます。
これで明示的な型変換ができました。
実際にコンパイルして試してみましょう。
今度は警告が出ることなくコンパイルできました。
このような明示的な型変換のことを「キャスト」といいますので覚えておいてください。
ほかのキャスト
実は型のキャストにはほかにもいくつかあります。
ここでは名前だけ挙げておきますので、ご興味のある方はご自身で調べてみてください(まだちょっと難しいものが多いと思います)。
- C形式のキャスト
- 関数形式のキャスト
- dynamic_cast
- const_cast
- reinterpret_cast
このうちC形式のキャストは見る機会が多いと思いますので簡単に紹介しておきます。
上のソースコードのように、C形式のキャストでは丸括弧で変換する型を囲んで式の前に付けます。
今回は式が単なる変数だけだったのでそのままにしましたが、たとえばi + 1のような式であれば、式全体を括弧で囲んで(unsigned int)(i + 1)のように書いてください。
キャストが有効な例
せっかくなので、もっとキャストが有効な例を見ておくことにしましょう。
このようにint型の変数aとbを使って割り算した結果を出力すると、結果は次のようになります。
整数どうしの割り算なので結果も整数になりますから「3」が出力されています。
これが期待した結果ならいいんですが、「3.333…」という結果が欲しかったとしたらこのままではダメです。
こういうときも明示的な型変換が役に立ちます。
このように一方の変数をキャストしてあげると……
ちゃんと小数点以下も出力されるようになりました。
本来であれば変数aもbもキャストすべきなんですが、どちらか一方をキャストしておけばOKです。
型が異なるものどうしを演算仕様とすると、より表現できる範囲が広い型に暗黙的に型変換されるからです。
int型とdouble型ではdouble型の方が表現できる範囲が広いですから両方がdouble型にそろえてから演算してくれます。
型推論
型変換とは直接関係ないのですが、この機会に「型推論」という機能も紹介しておきます。
上のソースコードのように、変数を宣言するときに型の代わりに「auto」と書いてあげると、指定した初期値の型が自動的に使われます。
初期値がない場合は型がわからなくなってしまうのでautoを使うことはできませんので、必ず初期値が必要になります。
すごく便利な機能ですし、目にする機会も多いと思いますので是非覚えておいてください。
autoを使った型推論ではひとつ注意が必要です。
二重引用符で囲んだ文字列が初期値の場合、stringではない別の型に推論されてしまいます。
文字列の場合はautoは避けて「string」と書くか、次のようにしてください。
まず、ソースファイルの冒頭(#include <string>よりあと)でusing namespace std::literals;と書いてください。
そして、変数の初期値になる文字列には最後に「s」を付けるようにしてください。
その際、二重引用符とsの間にスペースを入れてはいけません。
これで変数はstring型として宣言されます。
今回はデータ型の変換と(おまけで)型推論を見ていきました。
どれも大事ですのでしっかり身に付けておきましょう!