6日でできる 新C言語入門|暗黙の型変換とキャストの違い

以下に、記事としてそのまま使いやすい形で作成しました。

型が変わると、値の見え方も変わる。
暗黙の型変換とキャストを理解して、C言語のデータを安全に扱おう。

C言語では、int、double、charなど、値の種類に応じてデータ型を使い分けます。整数を扱うならint型、小数を扱うならdouble型、1文字を扱うならchar型のように、変数には入れられる値の種類があります。

プログラムを書いていると、異なる型同士で値を代入したり、計算したりする場面がよく出てきます。たとえば、double型の小数をint型の変数に入れたい場合や、int型の整数をdouble型として計算したい場合です。このようなときに発生するのが型変換です。

型変換には、大きく分けて2つの考え方があります。1つは、C言語が自動的に型を変換する暗黙の型変換です。もう1つは、プログラマが型を指定して変換する明示的な型変換です。この明示的な型変換をキャストと呼びます。

暗黙の型変換は、コードを短く書ける一方で、意図しないデータの損失が起こることがあります。特に、double型からint型へ変換すると、小数点以下が切り捨てられます。キャストを使うと、型を変換する意図をコード上にはっきり示せるため、読みやすさや安全性の面で役立ちます。

この記事では、C言語のデータ型の基本、暗黙の型変換とキャストの違い、実数から整数へ変換するときの注意点、char型とint型の関係などを、サンプルプログラムを使いながらやさしく解説していきます。

データ型は値の種類を決めるもの

C言語では、変数を使うときに型を指定します。型とは、その変数にどのような種類の値を入れるのかを決めるものです。

データ型主な内容値の例
int整数を扱う10、-5、0
double小数を含む数値を扱う3.14、-2.5、0.0
char1文字分のデータを扱うA、1など

int型は、小数点を含まない整数を扱います。点数、個数、年齢、回数などを表すときによく使います。double型は、小数を含む数値を扱います。平均値、割合、計測値などを表すときに便利です。

char型は、基本的には1文字を扱う型です。ただし、日本語の文字は多くの環境で複数バイトとして表現されるため、char型1つに日本語1文字を単純に入れて扱うのは注意が必要です。入門段階では、char型は半角英字や数字1文字を扱うものとして理解すると分かりやすいです。

図:C言語の主なデータ型と入れられる値

この図から分かること

この図から分かるのは、C言語では変数の型によって扱える値の種類が変わるという点です。

int型は整数、double型は小数を含む数値、char型は1文字分のデータを扱います。型を正しく理解しておくと、代入や計算を行ったときに、値がどのように扱われるのかを予測しやすくなります。

型変換とは

型変換とは、あるデータ型の値を別のデータ型として扱うことです。C言語では、異なる型同士で代入や計算を行うと、必要に応じて型変換が発生します。

たとえば、double型の値をint型の変数に入れる場合、double型の値はint型に変換されます。逆に、int型の値をdouble型として扱う場合もあります。

変換の例内容
doubleからint小数を整数として扱う
intからdouble整数を小数として扱う
charからint文字を文字コードの整数値として扱う
intからchar整数値を文字として扱う

型変換そのものは便利な仕組みですが、注意も必要です。特に、情報量の多い型から少ない型へ変換すると、値の一部が失われることがあります。たとえば、3.99をint型に変換すると3になります。小数点以下の.99は保存されません。

暗黙の型変換とは

暗黙の型変換とは、プログラマが明示的に指定しなくても、C言語が自動的に行う型変換のことです。

たとえば、double型の値をint型の変数に代入すると、C言語は必要に応じてdouble型からint型へ変換します。ただし、このとき小数点以下が切り捨てられます。

書き方起こること
int n = 3.14;doubleの3.14がintへ変換され、nには3が入る
double d = 5;intの5がdoubleへ変換され、dには5.000000として扱われる
int code = 'A';文字Aが文字コードの整数値として扱われる

暗黙の型変換は便利ですが、意図しない変換が起こることもあります。特に、小数から整数への変換では、データが失われる可能性があります。そのため、コンパイラや開発環境によっては警告が表示されることがあります。

キャストとは

キャストとは、プログラマが明示的に型変換を指定する書き方です。C言語では、変換したい型名を丸かっこで書き、その後ろに変換したい値や式を書きます。

書き方意味
(int)3.143.14をint型として扱う
(double)55をdouble型として扱う
(int)'A'文字Aをint型として扱う
(char)65整数65をchar型として扱う

キャストを使うと、型を変換する意図をコード上にはっきり示せます。たとえば、int n = (int)3.14;と書けば、小数点以下が切り捨てられることを分かったうえで整数に変換している、と読み取れます。

暗黙の型変換では、C言語が自動的に変換します。一方、キャストでは、プログラマがこの型に変換する、と明示します。この違いがとても大切です。

図:暗黙の型変換とキャストの違い

この図から分かること

この図から分かるのは、暗黙の型変換とキャストでは、型が変わる結果だけでなく、コードから読み取れる意図が違うという点です。

int n = 3.14;では、C言語が自動的にdouble型からint型へ変換します。一方、int n = (int)3.14;では、プログラマが意図してint型に変換していることが明確になります。小数点以下が切り捨てられるような場面では、キャストを使うことで意図を示しやすくなります。

暗黙の型変換とキャストを確認するサンプルプログラム

次のプログラムでは、double型の値をint型へ変換したり、int型の値をdouble型へ変換したりします。暗黙の型変換とキャストの違いを、表示結果から確認してみましょう。

プロジェクト/ファイル名: Lesson18_1/main.c

#include <stdio.h>

int main(void) {
    // 小数を扱うdouble型の変数を用意する
    double price_rate = 8.75;
    double weight = 12.48;

    // 整数を扱うint型の変数を用意する
    int rate_int;
    int weight_int;

    // キャストを書かずにdoubleからintへ代入する
    rate_int = price_rate;

    // キャストを使ってdoubleからintへ変換する
    weight_int = (int)weight;

    // 変換前のdouble型の値を表示する
    printf("price_rate = %f, weight = %f\n", price_rate, weight);

    // 変換後のint型の値を表示する
    printf("rate_int = %d, weight_int = %d\n", rate_int, weight_int);

    // int型の値をdouble型として扱う
    double converted_value = (double)weight_int;

    // intからdoubleへ変換した値を表示する
    printf("weight_intをdouble型に変換した値: %f\n", converted_value);

    return 0;
}

実行結果

price_rate = 8.750000, weight = 12.480000
rate_int = 8, weight_int = 12
weight_intをdouble型に変換した値: 12.000000

このプログラムでは、price_rateとweightがdouble型です。どちらも小数を含む値です。

rate_int = price_rate;では、キャストを書いていません。しかし、rate_intはint型なので、代入時にdouble型からint型への暗黙の型変換が行われます。その結果、8.75の小数点以下が切り捨てられ、rate_intには8が入ります。

weight_int = (int)weight;では、(int)を使って明示的にint型へ変換しています。結果として、12.48は12になります。暗黙の型変換と同じように小数点以下は切り捨てられますが、こちらは変換する意図がコード上で分かりやすくなっています。

実数から整数へ変換すると小数点以下が切り捨てられる

double型からint型へ変換すると、小数点以下は切り捨てられます。四捨五入ではありません。

変換前の値int型へ変換した結果
3.143
7.897
-2.5-2
10.010

ここで大切なのは、3.99をint型に変換しても4にはならないという点です。小数点以下がそのまま取り除かれるため、結果は3です。

四捨五入したい場合は、単純なキャストだけでは不十分です。四捨五入を行う処理を別に考える必要があります。入門段階では、doubleからintへの変換では小数点以下が切り捨てられる、と覚えておきましょう。

intからdoubleへの変換は情報が増えるのではなく表現が変わる

int型の値をdouble型に変換すると、小数を扱える形式になります。たとえば、5をdouble型に変換すると5.000000のように表示されます。

ただし、これは値そのものが細かくなったわけではありません。もともと整数として5だった値を、小数を扱える型として表現しているだけです。

変換結果のイメージ
(double)55.000000
(double)1010.000000
(double)00.000000

intからdoubleへの変換では、小数点以下の情報が新しく生まれるわけではありません。整数を小数形式で扱えるようになる、と考えると分かりやすいです。

平均計算ではキャストが役立つ

キャストがよく役立つ場面の1つが平均値の計算です。C言語では、整数同士を割り算すると、結果も整数として扱われます。そのため、小数部分が切り捨てられます。

たとえば、5 / 2の結果は2です。2.5にはなりません。小数として計算したい場合は、どちらか一方をdouble型に変換します。

結果の考え方
5 / 2整数同士の割り算なので2
(double)5 / 2double型を含む計算なので2.500000
5 / (double)2double型を含む計算なので2.500000
(double)(5 / 2)先に整数の割り算が行われるので2.000000

注意したいのは、キャストをかける位置です。(double)(5 / 2)と書くと、先に5 / 2が整数として計算され、結果の2がdouble型になります。そのため、2.000000になります。

小数の計算結果がほしい場合は、割り算をする前にどちらかの値をdouble型に変換する必要があります。

char型とint型の変換

char型は文字を扱う型ですが、コンピュータ内部では文字コードという数値として管理されています。そのため、char型の値をint型として表示すると、対応する文字コードの数値を確認できます。

変換結果の例
(int)文字AASCIIコードでは65
(char)65ASCII環境では文字A
(int)文字1ASCIIコードでは49

半角英字や数字は、ASCIIコードとして分かりやすく確認できます。たとえば、文字AはASCIIコードで65に対応します。

ただし、日本語の文字は多くの場合、複数バイトで表現されます。そのため、char型1つで日本語1文字を扱うのは環境によって難しい場合があります。char型とint型の変換を学ぶときは、まず半角英字を使うと理解しやすいです。

図:型変換で値の表現が変わる

この図から分かること

この図から分かるのは、型変換によって値の表現や扱われ方が変わるという点です。

double型の8.75をint型に変換すると、小数点以下が切り捨てられて8になります。また、char型の文字Aをint型として扱うと、文字コードの65として見ることができます。型変換では、値の見た目だけでなく、内部でどのように扱われるかも意識することが大切です。

暗黙の型変換で警告が出ることがある

暗黙の型変換は、C言語が自動的に行ってくれる便利な仕組みです。しかし、変換によって情報が失われる可能性がある場合、コンパイラや開発環境が警告を出すことがあります。

特に、double型からint型への代入では、小数点以下が失われます。そのため、データが失われる可能性があるという意味の警告が出る場合があります。

変換注意点
doubleからint小数点以下が切り捨てられる
大きな整数から小さな型値の範囲を超える可能性がある
intからchar対応する文字や値の範囲に注意が必要
符号ありと符号なしの変換予想と違う値になる場合がある

警告はエラーではないため、プログラムが実行できることもあります。しかし、警告には重要な意味があります。特に型変換に関する警告は、意図しないデータの損失やバグにつながる可能性があるため、無視せず確認することが大切です。

キャストは意図を伝えるために使う

キャストを使う大きな目的は、型変換の意図を明確にすることです。

たとえば、int n = value;と書いているだけでは、valueがdouble型だった場合、小数点以下が失われることを意識しているのか、うっかり書いたのか分かりにくいです。

一方、int n = (int)value;と書いてあれば、プログラマが意図してint型へ変換していることが伝わります。

書き方読み取れること
n = value;暗黙に変換されている可能性がある
n = (int)value;int型へ変換する意図がある
average = total / count;整数同士の割り算かもしれない
average = (double)total / count;小数として平均を求めたい意図が分かる

キャストは、単に警告を消すためだけに使うものではありません。なぜその型に変換するのかを理解したうえで使うことが大切です。

キャストを使うときの注意点

キャストは便利ですが、使えばすべて安全になるわけではありません。キャストは型を変換する書き方であり、データの損失そのものを防ぐものではないからです。

たとえば、(int)7.89と書けば7になります。キャストを書いたからといって、小数点以下が保存されるわけではありません。

注意点内容
データ損失は防げないdoubleからintでは小数点以下が失われる
キャスト位置が重要割り算の前に変換するか後に変換するかで結果が変わる
警告を隠す目的で乱用しない本当に安全な変換か確認する
変換先の範囲に注意する値が型の範囲を超えると問題になる
日本語文字の扱いに注意するchar型1つで扱えない場合がある

キャストは、型変換の意図を明示するための道具です。使う前に、変換によって何が起こるのか、値が失われないか、結果が期待どおりかを確認しましょう。

暗黙の型変換とキャストを使い分ける考え方

暗黙の型変換とキャストは、どちらも型を変換する仕組みですが、使い分けの考え方があります。

場面考え方
intからdoubleへ変換情報が失われにくく、自然な変換として扱いやすい
doubleからintへ変換小数点以下が失われるため、キャストで意図を示すとよい
平均値を求める割り算の前にdoubleへ変換する
charを文字コードとして見る(int)を使うと意図が分かりやすい
警告が出る変換なぜ警告が出るのか確認してから対応する

基本的には、データが失われる可能性がある変換では、キャストを使って意図を明確にすると読みやすくなります。ただし、キャストを書けば安全になるわけではないため、変換結果を理解して使うことが大切です。

型変換を理解するとバグを防ぎやすくなる

C言語では、型の違いによって計算結果や代入結果が変わります。特に、整数と小数の計算では、思った結果にならないことがあります。

たとえば、平均値を求めるつもりでtotal / countと書いたとき、totalとcountがどちらもint型なら、結果は整数になります。小数が必要な場合は、(double)total / countのように、計算前に型を変換する必要があります。

型変換を理解しておくと、次のようなトラブルを防ぎやすくなります。

起こりやすい問題原因
小数が表示されない整数同士で割り算している
小数点以下が消えるdoubleをintに変換している
警告が出るデータが失われる可能性がある
文字が数値として表示されるcharをintとして扱っている
予想外の文字になるintをcharへ変換している

型変換は、C言語の学習が進むほど重要になります。変数、演算、関数、配列、ポインタなど、さまざまな場面で型の考え方が関係するためです。

キャストの理解はC言語らしい考え方につながる

C言語は、型を意識して書く言語です。どの変数にどの型の値が入り、計算のときにどの型として扱われ、代入のときにどのように変換されるのかを考えることが大切です。

暗黙の型変換は便利ですが、すべてを自動に任せると、意図しない結果になることがあります。キャストを使えば、型変換の意図をコードに残せます。ただし、キャストは魔法のように値を安全に変えるものではなく、変換に伴う切り捨てや範囲の問題を理解したうえで使う必要があります。

まずは、doubleからintでは小数点以下が切り捨てられること、intからdoubleでは小数形式として扱えるようになること、charとintは文字コードを通じて関係していることを押さえましょう。

型変換の動きを理解すると、C言語のプログラムを読む力が高まります。値がどの型として扱われているのかを意識できるようになると、計算結果の違いや警告の意味にも気づきやすくなります。