同一のプロジェクトで、同一のソースコードから関数を呼び出す (プロトタイプ宣言)
前のページで作成したプロジェクトに、関数を追加していきます。
手順
次の関数をソースコードの末尾に追加します
int myFunc()
{
return 123;
}
main 関数に次の行を追加します
int main()
{
printf("Hello World!\n");
printf("myFunc: %d\n", myFunc());
}
ソースコード全体としては次のようになっていることを確認します
(強調されている部分が今回追加された行です)
#include <stdio.h>
int main()
{
printf("Hello World!\n");
printf("myFunc: %d\n", myFunc());
}
int myFunc()
{
return 123;
}
ここで画面上部 [ローカル Windows デバッガー] を実行してみてください
そして、次のエラーダイアログが表示されることを確認します
次に画面下、[出力] ウインドウにエラー行を含むログが出力されていることに着目してください
ビルドを開始しました...
1>------ ビルド開始: プロジェクト: ConsoleApplication1, 構成: Debug Win32 ------
1>ConsoleApplication1.cpp
1>D:\User\Desktop\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp(6,28): error C3861: 'myFunc': 識別子が見つかりませんでした
1>プロジェクト "ConsoleApplication1.vcxproj" のビルドが終了しました -- 失敗。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
今後も様々なログと出合うことになると思います。
必ずログを読めるよう/読むようにしてください。
特に "error" が含まれている/いないに注意を向けてください。
さて、エラー行ですが意味はおおよそ次の通りです :
ConsoleApplication1.cpp の 6行目,28文字目から記述されている
myFunc なる識別子はこれまでに宣言/定義されていない
これまでに宣言/定義されていない、とはどう意味でしょうか。
9行目には myFunc 関数が定義されているのですが。
それは、
コンパイラが、obj ファイルを生成するため、ソースコードを1行目から順に処理を進めていった。
ところが myFunc の宣言/定義もなく、いきなり myFunc を実行しようとする記述があったため、エラーとした
といった具合です。
つまり、先ほどのエラーはコンパイラによるコンパイル処理の中で myFunc を使用(6行目)するより前に宣言も定義もされなかった、という意味です。
C言語では 9行目の myFunc 関数の定義だけでは駄目なのです。
コンパイル処理は各ソースコードについて1ファイルずつ、1行目から処理が行われること、処理中の行より後に定義された関数/変数を使用できない、ということを肝に銘じておいてください
方法は2つあります。①使用する行より前に宣言を追加する ②使用する行より前に定義を移動する、です。
ここでは①の方法をとります。
下記の行を追加してください
#include <stdio.h>
int myFunc();
int main()
{
printf("Hello World!\n");
printf("myFunc: %d\n", myFunc());
}
次に画面上部 [ローカル Windows デバッガー] を押下します
下記のような結果が表示されることを確認します
無事に追加した関数を呼び出すことができました
なお、先ほど追加したような行のことを "プロトタイプ宣言" といいます。
要点をまとめます
- コンパイルは1ファイルずつ、上から1行ずつ処理される
- 変数/関数はその行より前に定義/宣言がない状態で使用されるとエラーとなる
- 変数/関数を使用する際はソースの上部に宣言を追加する
【補足】
このページでは本来行われているプリプロセスという処理についてあえて言及していません。プリプロセス処理については今後説明する予定です。