第2章18 明示的な型変換(型キャスト)を知る@イチからゲーム作りで覚えるC言語

明示的な型変換

明示的な型変換

イチからゲーム作りで覚えるC言語
連載ページ一覧へ
2章19 while文で繰り返し処理を作る
NEXT : 2章19 while文で繰り返し処理を作る
2章17 暗黙の型変換ルールを知る : PREV

この記事でやること

前回はプロジェクト「0140_implementation」を新しく作り、暗黙の型変換ルールについてお話ししました。
今回は、新しくプロジェクト「0145_cast」を作り、明示的に型変換を行う型キャストについてお話します。この書き方を知っていることで、異なる整数型から整数型への代入を行ったり、浮動小数点から小数点以下部分を取り出したりが行えるようになります。

この記事はゆる~くC言語でコンソールゲームを作りながらプログラミングを学ぶための連載記事です。シリーズものですので記事の一覧はこちらを参照してくださいね。

型キャストを行うプログラム

型キャストを行うソースコードを実際にプログラムを動かして結果を見てみましょう。

#include <stdio.h>
#include <limits.h>
int main() {
 unsigned char small;
 unsigned int big = 257;
 float progress = 12.3456f;
 printf( "unsigned char 型のサイズは 1 バイト。代入できる最大値は %d \n"
     , UCHAR_MAX);
 printf( "unsigned int 型のサイズは %d バイト。\n"
     , sizeof(int));
 // unsigned int から unsigned char への型キャスト
 small = (unsigned char)big;
 // 結果表示
 printf("small に収まる 1 バイトを big からキャストした結果、small は %d\n", small);
 printf("progress の実数部分は %d\n", (int)progress);
 printf("progress の小数部分は %f\n", progress - (int)progress);
}

このコードを実行してみるとこんな結果になったかと思います。

unsigned char 型のサイズは 1 バイト。代入できる最大値は 255
unsigned int 型のサイズは 4 バイト。
small に収まる 1 バイトを big からキャストした結果、small は 1
progress の実数部分は 12
progress の小数部分は 0.345600

unsigned int型の整数 257 を unsigned char型の変数に代入して、結果を表示しています。また、float型(浮動小数点数型)の変数の実数部と小数部をそれぞれ取り出して表示しています。

型キャストとは

C言語では int 型を short 型にする、short 型を char 型にするなど、異なる指定した型に明示的に変換することができます。この型の変換のことを型キャストと呼びます。書き方は下のような形です。

( 変換後の型 ) 変換元の整数や変数

具体的には下のように使います。

long dekai = 1000L;
short tiisai = ( short ) dekai;

long型の変数 dekai を short 型に型キャストして、変数 tiisai に代入しています。

ソースコードを追ってみよう

今回のソースコードの処理を一つ一つ見ていきましょう。
4~6行目で変数の宣言と初期化を行っています。

unsigned char small;
unsigned int big = 257;
float progress = 12.3456f;

6行目の処理が終わった時点で、変数と中身は下のような状態になっています。

  • unsinged char 型(正の整数のみ入力可能な char 型)の変数 small を宣言。初期化はしていない
  • unsigned int 型(正の整数のみ入力可能な int 型)の変数 big を整数 257 で初期化
  • float 型の変数 progress を浮動小数点数 12.3456 で初期化
printf( "unsigned char 型のサイズは 1 バイト。代入できる最大値は %d \n"
      , UCHAR_MAX);
printf( "unsigned int 型のサイズは %d バイト。\n"
      , sizeof(int));

7~11行目では、char 型と int 型のサイズと、持てる最大の値を表示しています。
なお、7&8行目と9&10行目はそれぞれ一つの printf 関数で、見やすくするために途中で改行を入れています。

前のページでお話しました CHAR_MAX は char型の持てる最大の数が入っています。
今回 printf で表示している、 UCHAR_MAX は unsigned char 型の最大の数を表示します。
unsigned char 型は、負の数がもてないかわりに、0 から 255 までの数を代入することができます。(char 型は -128 から 127 の数を代入することができました。)

small = (unsigned char)big;

12行目の右辺で unsigned int 型の変数 big を、unsigned char 型に型キャストしています。さて、unsigned char 型に入れられる値は最大で 255 まででしたが、それ以上の値を型キャストで入れようとするとどうなるでしょうか。

小さいサイズへの型キャスト

unsigned int 型は 4 バイトのメモリを持つことができ、 その数値は 4×8 ビット = 32ビットで表現できます。つまり 0 と 1 のビットが 32 個あり、その組み合わせで数値を表現しています。

例えば 1、2、3、4 …という数値は以下のようなビット組み合わせになります。
(見やすさのため、1バイト(8ビット)ごとに区切っています。)

unsigned int をビット単位で確認

unsigned int をビット単位で確認

例えば unsigned int で 257 という数値は下のようなビットとなります。

unsigned int で 257

unsigned int で 257

今回の型キャストで、1バイトだけを切り出すと、下のように一部分しか取れない状態となります。

4バイトを1バイトにキャスト

4バイトを1バイトにキャスト

1バイト以上の範囲は破棄されます。その結果、「(unsigned char)big」の結果は 1 となります。その結果を左辺の変数 small に代入しているということになります。
結果は以下の14行目で表示している通りとなります。

printf("small に収まる 1 バイトを big からキャストした結果、small は %d\n", small);

浮動小数点数(float型やdouble型)をint型に型キャスト

浮動小数点数(float型やdouble型) を int 型に型キャストするとどのような結果になるでしょうか。実際に 15 行目、16 行目で確認しています。

 printf("progress の実数部分は %d\n", (int)progress);
 printf("progress の小数部分は %f\n", progress - (int)progress);

(int)progress で、浮動小数点数型(float型)の変数 progress を int 型に型キャストしています。ここで、 progress の中身「12.3456」の小数点以下は切り捨てされ、実数部分の整数「12」のみ取得されます。その結果、15行目は 12 が printf関数の「%d」で表示さます。

整数部と小数部

整数部と小数部

16行目は、15行目と同様、(int)progress を使っています。 (int)progress は整数12となりますので、「progress – (int)progress」は「12.3456 – 12」の計算となります。
結果、答えの 0.3456 が得られ、浮動小数点数を表示する printf の %f 記号部分に表示されます。

あとがき

今回はあまりゲーム要素のないプログラムでしたが、型キャストは今後も頻繁に発生する計算の一つですので、早めにお話しておきました。暗黙の型変換と似た機能ですので、あわせて覚えていただければと思います。

イチからゲーム作りで覚えるC言語
連載ページ一覧へ
2章19 while文で繰り返し処理を作る
NEXT : 2章19 while文で繰り返し処理を作る
2章17 暗黙の型変換ルールを知る : PREV

非常に参考になったサイトさまや、参考文献など

ページの更新履歴

更新日 更新内容
2018/7/18 ページ公開
2018/9/8 アイキャッチ画像、トップ画像を追加。