前回作ったプログラムでちょっと実験してみましょう。
kaku という関数は、プログラムの中で
int kaku(int uketori)
と書かれています。これは、int 型の値を渡してやると処理された結果が int 型で返ってくる、ということを表しています。では、渡す型を誤るとどうなるのでしょうか。試しに、「.ToInt()」を消して実行してみましょう。(なお、「.ToInt()」を取り去った残りの「EditA->Text」はAnsiString型です。)
void __fastcall TForm1::ButtonCalcClick(TObject *Sender)
{
EditA->Text = kaku(EditA->Text);
EditB->Text = kaku(EditB->Text.ToInt());
}
実行しようとすると、次のようにエラーが出ますね。
Cannot convert 'System::AnsiString' to 'int'.
このエラーの意味を調べてみましょう。この行を選択して青くし、「F1」を押してください。ヘルプが起動し、次のように表示されます。
Cannot convert 'type1' to 'type2' コンパイラメッセージ
'type1' を 'type2' に変換できない
これはつまり、AnsiString 型を int 型に変換することができない、ということです。int 型しか受け付けない関数 kaku に AnsiString 型を渡そうとしたからエラーになったのです。
プログラムは元に戻しておきましょう。
ここは細かい話なので、読み飛ばして先に進んでも構いません。
関数 kaku は
int kaku(int uketori)
と書かれているので、「あれ、関数か返す型は int 型だから、EditA->Text も int 型なのか?」という疑問を持った方もいると思いますが、実は EditA->Text は int 型ではなく AnsiString 型であり、この AnsiString 型は int 型を渡されても都合がいいように解釈して受け取ることができるようになっているのです。
もう1つ実験してみましょう。
今度は、関数 kaku を ButtonCalc の OnClick の後に移動させます。
void __fastcall TForm1::ButtonCalcClick(TObject *Sender)
{
EditA->Text = kaku(EditA->Text.ToInt());
EditB->Text = kaku(EditB->Text.ToInt());
}
int kaku(int uketori)
{
int kotae;
if (uketori % 2 == 0) { // 偶数なら
kotae = uketori / 2;
} else { // 奇数なら
kotae = uketori * 3 + 1;
}
return kotae; // 計算結果を返す
}
実行してみましょう。「Call to undefined function 'kaku'」というエラーが出ましたね。これは「未定義の関数 'kaku' を呼び出した」というエラーです。エラーメッセージをダブルクリックすると
EditA->Text = kaku(EditA->Text.ToInt());
の行が茶色くなるので、この行に問題があることが分かります。関数 kaku の場所を移動する前は問題がなかったのに、なぜ今はエラーが出るのでしょうか。
これは、コンピュータが関数 kaku の型チェックを行おうとしているためです。さっきのプログラムでは、コンピュータがプログラムコードを上から読んでいくときに、先に
int kaku(int uketori)
が現れて関数 kaku の規格が分かり、その後で
EditA->Text = kaku(EditA->Text.ToInt());
というように関数 kaku を呼び出す行が現れたので、関数が正しく呼び出されているかどうか、型チェックを行うことができました。関数 kaku を後に持ってくると、コンピュータは関数 kaku に渡す型、関数 kaku が受け取る型の情報を得る前に
EditA->Text = kaku(EditA->Text.ToInt());
に遭遇してしまい、型チェックができません。そのため「Call to undefined function 'kaku'」というエラーが出たのです。