https://youtu.be/pjBMlK_dlHQ
\textcolor{pink}{四国めたん: }教師役ですわ
\textcolor{lime}{ずんだもん: }生徒役なのだ
\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです
\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう
\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今まで関数と云えばC標準関数かメイン関数と同じファイル上に作成した関数でしたわ
\footnotesize \textcolor{lime}{ずんだもん:} そのとおりだったのだ
\footnotesize \textcolor{pink}{四国めたん:} これはこれで問題ないのですが、自作の関数については、数が多くなってくると管理が大変になってきますわ
\footnotesize \textcolor{lime}{ずんだもん:} たしかに...
\footnotesize \textcolor{pink}{四国めたん:} そのため、今回は関数を別のファイルに作成するためのお話しをしますわ
関数ってファイルを分けられるんです
\footnotesize \textcolor{pink}{四国めたん:} 今までのサンプルプログラムでは、メイン関数と、その他の関数の組み合わせを1つのファイル"hello_world.c"に作成していましたわ
\footnotesize \textcolor{lime}{ずんだもん:} そのとおりなのだ
\footnotesize \textcolor{pink}{四国めたん:} 実は、関数については、別のファイルに作成することが可能ですわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} C言語に限らず、ほとんどのプログラミング言語では、この機能をサポートしていますわ
別ファイルにするメリットは?
\footnotesize \textcolor{lime}{ずんだもん:} ところで、別ファイルに関数を作成するメリットはなんなのだ?
\footnotesize \textcolor{pink}{四国めたん:} 幾つもあるのですが、とりあえず3つのメリットを挙げておきますわね
- ファイルのサイズを小さくできる
- 関数をグループ分けできる
- プログラムの作成時間が短くなる
\footnotesize \textcolor{lime}{ずんだもん:} それぞれについて、詳しく教えてほしいのだ
\footnotesize \textcolor{pink}{四国めたん:} わかりましたわ
ファイルのサイズを小さくできる
\footnotesize \textcolor{pink}{四国めたん:} まず、関数が多くなって、ファイルのサイズが大きくなると、編集するにも確認するにも大変になってきますわね
\footnotesize \textcolor{lime}{ずんだもん:} そのとおりなのだ
\footnotesize \textcolor{pink}{四国めたん:} そこで、関数を別のファイルに置くことで、ひとつひとつのファイルのサイズを小さくすることができますわ
\footnotesize \textcolor{lime}{ずんだもん:} たしかに...
\footnotesize \textcolor{pink}{四国めたん:} その結果として、関数の見直しやデバッグなどが容易になりますわ
\footnotesize \textcolor{lime}{ずんだもん:} 素晴らしいのだ
関数をグループ分けできる
\footnotesize \textcolor{pink}{四国めたん:} 次に、関数をファイル毎にグループ分けすることで、プログラムを把握し易くなりますわ
\footnotesize \textcolor{lime}{ずんだもん:} グループ分け?
\footnotesize \textcolor{pink}{四国めたん:} はい、特に機能毎に関数をまとめて、ファイルを分ければ、プログラムの保守が容易になりますわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} 例えば、他のプログラムで似たような機能を必要とした際には、ファイルを使いまわすだけでOKですわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、新たに関数を作成する手間が省けるのだ
\footnotesize \textcolor{pink}{四国めたん:} もし自作の関数をグループ分けしていなければ、必要な機能の関数を探してコピペするなどの手間が発生しますわ
プログラム作成時間が短くなる
\footnotesize \textcolor{pink}{四国めたん:} 最後に、プログラムのコンパイルは、ファイル毎に行われますわ
\footnotesize \textcolor{pink}{四国めたん:} ですので、プログラム作成時に、編集のないファイルについては、コンパイルが省略されるのですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、その分、プログラム作成時間が短くなるのだ
\footnotesize \textcolor{pink}{四国めたん:} 小さなプログラムではあまりメリットに感じませんが、大きなプログラムでは、かなりのメリットですわね
関数を別ファイルに…
\footnotesize \textcolor{pink}{四国めたん:} とりあえず四則演算を行う関数を別ファイルに作成して、呼び出すサンプルプログラムを作成してみましょう
\footnotesize \textcolor{lime}{ずんだもん:} よろしくおねがいするのだ
\footnotesize \textcolor{pink}{四国めたん:} まずは、新しいファイルを作成していきましょう
-
ソリューションエクスプローラー の Project1 の ソースファイル を右クリック
-
追加 → 新しい項目... を選択
-
新しい項目の追加 ウィンドウで 名前 を"calc.c"に変更
-
追加 ボタンをクリック
\footnotesize \textcolor{pink}{四国めたん:} まず、 ソリューションエクスプローラー の Project1 の ソースファイル を右クリックしますわ
\footnotesize \textcolor{pink}{四国めたん:} 次に、 追加 から 新しい項目... を選択しますわね
\footnotesize \textcolor{pink}{四国めたん:} 新しい項目の追加 ウィンドウが開いたら、 名前 を"calc.c"に変更しますわ
\footnotesize \textcolor{pink}{四国めたん:} 最後に 追加 ボタンをクリックすれば"calc.c"ファイルが作成されますわ
\footnotesize \textcolor{pink}{四国めたん:} なお、ファイル名は適当でかまいませんが、拡張子は".c"にしてくださいね
\footnotesize \textcolor{lime}{ずんだもん:} 今回は"calc.c"なのだ
\footnotesize \textcolor{pink}{四国めたん:} それでは、ファイルに関数を作成して行きますわ
\footnotesize \textcolor{lime}{ずんだもん:} どのような関数を作るのだ?
\footnotesize \textcolor{pink}{四国めたん:} とりあえず、積和演算を行う関数multi_add
を定義しますわね
#include <stdio.h>
/// <summary>
/// 積和演算 a * b + c
/// </summary>
/// <param name="a">被乗数</param>
/// <param name="b">乗数</param>
/// <param name="c">加数</param>
/// <returns>積和の結果</returns>
int multi_add(int a, int b, int c) {
int d = a * b + c;
return d;
}
\footnotesize \textcolor{lime}{ずんだもん:} これだけのプログラムに#include <stdio.h>
は必要なのか?
\footnotesize \textcolor{pink}{四国めたん:} たしかにprintf
などの入出力関数は使用していませんので、本来は#include <stdio.h>
は必要ありませんわ
\footnotesize \textcolor{pink}{四国めたん:} ただ、#include <stdio.h>
を記述しても悪い影響はありませんし、後々、便利な面もあるので記述していますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{lime}{ずんだもん:} ところで、コメント記号がダブルスラッシュ"//"ではなく、トリプルスラッシュ"///"になっているのだが...
\footnotesize \textcolor{pink}{四国めたん:} はい、これは ドキュメントジェネレータ であるXMLドキュメント向けのコメント記号ですわ
\footnotesize \textcolor{lime}{ずんだもん:} ドキュメントジェネレータ ?
\footnotesize \textcolor{pink}{四国めたん:} はい、コメントなどからプログラムの説明書などを自動的に作成するアプリケーションですわね
\footnotesize \textcolor{lime}{ずんだもん:} お~、便利なアプリケーションなのだ
\footnotesize \textcolor{pink}{四国めたん:} とりあえず、トリプルスラッシュ"///"以下はコメントということで、スルーしておいてくださいね
\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ
別ファイルの関数を呼び出します
\footnotesize \textcolor{pink}{四国めたん:} 別ファイルに関数を定義しましたので、メイン関数から呼び出してみましょう
\footnotesize \textcolor{lime}{ずんだもん:} "hello_world.c"を変更していくのだ
#include <stdio.h>
void main() {
int a = 3;
int b = 4;
int c = 5;
int d = multi_add(a, b, c);
printf("積和の答えは%dです。\n", d);
}
\footnotesize \textcolor{lime}{ずんだもん:} 「積和の答えは17です。」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、実行すると正しい答えが表示されます。
\footnotesize \textcolor{lime}{ずんだもん:} なんか、警告が出ていないか?
\footnotesize \textcolor{pink}{四国めたん:} はい、 C4013 関数 multi_add は定義されていません。int型の値を返す外部関数と見なします。 と云う警告が出ていますわね
\footnotesize \textcolor{lime}{ずんだもん:} multi_add
関数は定義していたはずなのだ
\footnotesize \textcolor{pink}{四国めたん:} これは以前に関数についての解説をした際に触れましたが、関数は使用する前に定義または宣言されている必要があります。
\footnotesize \textcolor{lime}{ずんだもん:} おぼえているのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回、multi_add
関数は別のファイルでは定義されています
\footnotesize \textcolor{pink}{四国めたん:} ですが、"hello_world.c"ファイル内では定義も宣言もされていませんので、警告が出ていますわ
\footnotesize \textcolor{lime}{ずんだもん:} でも、ちゃんと実行できたのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回はたまたまmulti_add
が int型 を返す関数でしたので問題になりませんでしたが、通常は色々と問題が発生しますわね
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか...
\footnotesize \textcolor{pink}{四国めたん:} ですので、メイン関数の前にmulti_add
関数の宣言を追加してみましょう
#include <stdio.h>
int multi_add(int a, int b, int c);
void main() {
int a = 3;
int b = 4;
int c = 5;
int d = multi_add(a, b, c);
printf("積和の答えは%dです。\n", d);
}
\footnotesize \textcolor{lime}{ずんだもん:} お~、警告が出なくなったのだ
ヘッダーファイルを使いましょう
\footnotesize \textcolor{pink}{四国めたん:} とりあえず、関数を別のファイルに定義することはできましたわ
\footnotesize \textcolor{lime}{ずんだもん:} 別ファイルに定義した関数の宣言を行うことで警告が出ないようになったのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、関数の宣言については、関数の数が少ない場合には問題になりませんわ
\footnotesize \textcolor{lime}{ずんだもん:} 関数が沢山あったら、毎回、宣言するだけでも大変なのだ
\footnotesize \textcolor{pink}{四国めたん:} そのため、通常は ヘッダーファイル を作成して、そこに関数の宣言をまとめますわ
\footnotesize \textcolor{lime}{ずんだもん:} ヘッダーファイル ?
\footnotesize \textcolor{pink}{四国めたん:} ヘッダーファイル は、事前に関数の宣言などを書いておきますわ
\footnotesize \textcolor{pink}{四国めたん:} それを#include
ディレクティブで読み込むことで、関数の宣言などを繰り返し書く手間を省くことができますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} "stdio.h"などが良い例で、printf
を始めとした入出力に関する関数の宣言が書かれていますわ
\footnotesize \textcolor{lime}{ずんだもん:} "stdio.h"は、読み込むだけで多くの入出力関数を使えるようになるので便利なのだ
ヘッダーファイルを作りましょう
\footnotesize \textcolor{pink}{四国めたん:} それではヘッダーファイルを作成してみましょう
-
ソリューションエクスプローラー の Project1 の ヘッダーファイル を右クリック
-
追加 → 新しい項目... を選択
-
新しい項目の追加 ウィンドウで 名前 を"calc.h"に変更
-
追加 ボタンをクリック
\footnotesize \textcolor{pink}{四国めたん:} まず、 ソリューションエクスプローラー の Project1 の ヘッダーファイル を右クリックしますわ
\footnotesize \textcolor{pink}{四国めたん:} 次に、 追加 から 新しい項目... を選択しますわね
\footnotesize \textcolor{pink}{四国めたん:} 新しい項目の追加 ウィンドウが開いたら、 名前 を"calc.h"に変更しますわ
\footnotesize \textcolor{pink}{四国めたん:} 最後に 追加 ボタンをクリックすれば"calc.h"ファイルが作成されますわ
\footnotesize \textcolor{pink}{四国めたん:} なお、ファイル名は適当でかまいませんが、関数を定義したファイル名と同じにすると判り易いと思いますわ
\footnotesize \textcolor{pink}{四国めたん:} また、拡張子は".h"にしてくださいね
\footnotesize \textcolor{lime}{ずんだもん:} 今回は"calc.h"なのだ
\footnotesize \textcolor{pink}{四国めたん:} ファイルの中身は、"multi_add"関数の宣言を行いますわ
#pragma once
#ifndef _INC_CALC
#define _INC_CALC
// <summary>
/// 積和演算 a * b + c
/// </summary>
/// <param name="a">被乗数</param>
/// <param name="b">乗数</param>
/// <param name="c">加数</param>
/// <returns>積和の結果</returns>
int multi_add(int a, int b, int c);
#endif // _INC_CALC
\footnotesize \textcolor{lime}{ずんだもん:} "multi_add"関数の宣言以外にも、いろいろと追加されているのだ
\footnotesize \textcolor{pink}{四国めたん:} それぞれについて、説明していきますわね
#pragma onceってなに?
\footnotesize \textcolor{pink}{四国めたん:} まずは#pragma once
ですわ
\footnotesize \textcolor{lime}{ずんだもん:} #pragma
?
\footnotesize \textcolor{pink}{四国めたん:} #pragma
は ディレクティブ のひとつで、システム固有の指示を行いますわ
\footnotesize \textcolor{lime}{ずんだもん:} #pragma once
は、Visual Studio限定の ディレクティブ なのか?
\footnotesize \textcolor{pink}{四国めたん:} その通りですわ
\footnotesize \textcolor{lime}{ずんだもん:} どのような指示になるのだ?
\footnotesize \textcolor{pink}{四国めたん:} #include
でヘッダーファイルを読み込んでいると、何回も同じファイルを読み込んでしまうことが多々ありますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、その際に、一度読み込んだことがあるファイルは読み飛ばすようにするための指示ですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} Visual Studio以外では無意味な指示ですが、悪さはしませんので、とりあえず書いておくといいですわ
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
インクルードガードを書きましょう
\footnotesize \textcolor{lime}{ずんだもん:} #pragma once
の後の#ifndef _INC_CALC
は何なのだ
\footnotesize \textcolor{pink}{四国めたん:} インクルードガード ですわね
\footnotesize \textcolor{lime}{ずんだもん:} インクルードガード ?
\footnotesize \textcolor{pink}{四国めたん:} #ifndef _INC_CALC
と#define _INC_CALC
、#endif // _INC_CALC
のセットのことですわ
\footnotesize \textcolor{lime}{ずんだもん:} どんな意味があるのだ?
\footnotesize \textcolor{pink}{四国めたん:} #pragma once
と、おおむね同じ働きをしますわ
\footnotesize \textcolor{lime}{ずんだもん:} おなじなら#pragma once
だけでいいのではないのか?
\footnotesize \textcolor{pink}{四国めたん:} #pragma once
とは異なり、Visual Studio以外でも機能しますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、詳しく教えてほしいのだ
\footnotesize \textcolor{pink}{四国めたん:} まず、#ifndef
ディレクティブは、続く定義名が定義されていない場合のみ、#endif
ディレクティブまでの行が有効になりますわ
\footnotesize \textcolor{lime}{ずんだもん:} 定義名は決まっているのか?
\footnotesize \textcolor{pink}{四国めたん:} 基本的に自由ですが、他と被らないように工夫する必要がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} どのような工夫をするのだ?
\footnotesize \textcolor{pink}{四国めたん:} 今回は_INC_CALC
としましたが、ファイル名の前に_INC_
を付けたり、後に_H
を付けたりする場合が多いですわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} #ifndef _INC_CALC
の次の行では#define _INC_CALC
で定義をおこなっていますわ
\footnotesize \textcolor{lime}{ずんだもん:} ここで定義をおこなうのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、初回にヘッダーファイルが読み込まれた際には、_INC_CALC
が定義されていませんのでヘッダーファイル内の記述が有効になりますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} そして、2回目以降のヘッダーファイルの読み込みでは、既に"_INC_CALC"が定義されていますので、ヘッダーファイル内の記述が無効になりますわ
\footnotesize \textcolor{lime}{ずんだもん:} つまり、#pragma once
と同じように、2回以上の読み込みを避けることができるということか
\footnotesize \textcolor{pink}{四国めたん:} その通りですわ
関数のコメントはどこに書く?
\footnotesize \textcolor{lime}{ずんだもん:} ところで、ヘッダーファイルの関数にもコメントを書いているのだな
\footnotesize \textcolor{pink}{四国めたん:} はい、関数のコメントについては、ヘッダーファイルの宣言のみに書く、プログラムファイルの定義のみに書く、両方に書くの3通りがありますわ
\footnotesize \textcolor{lime}{ずんだもん:} どれがいいのだ?
\footnotesize \textcolor{pink}{四国めたん:} 私のお勧めは、ヘッダーファイルの宣言のみに書くことですわ
\footnotesize \textcolor{lime}{ずんだもん:} なぜなのだ?
\footnotesize \textcolor{pink}{四国めたん:} まず、両方に書くと2度手間になりますわ
\footnotesize \textcolor{pink}{四国めたん:} また、両方に書いておくと、変更が必要な場合に、両方を修正する必要がありますわね
\footnotesize \textcolor{lime}{ずんだもん:} それは大変なのだ
\footnotesize \textcolor{pink}{四国めたん:} プログラムファイルのみに書いた場合は、ライブラリで提供する際に、コメントが消えてしまいますわ
\footnotesize \textcolor{lime}{ずんだもん:} ライブラリ?
\footnotesize \textcolor{pink}{四国めたん:} はい、プログラムファイルをコンパイルして得られたバイナリファイルのことですわね
\footnotesize \textcolor{pink}{四国めたん:} そして、ライブラリを提供する場合には、ヘッダーファイルも提供する必要がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、ヘッダーファイルにコメントを書いておけば、必ず見ることができるのか
\footnotesize \textcolor{pink}{四国めたん:} その通りですわ
ヘッダーファイルを呼び出します
\footnotesize \textcolor{pink}{四国めたん:} 作成したヘッダーファイルは、関数を定義したファイルの先頭と、関数を使用するファイルの先頭で読み込みますわ
\footnotesize \textcolor{lime}{ずんだもん:} 両方で読み込むのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、まずは関数を定義したファイル"calc.c"を見てみましょう
#include "calc.h"
#include <stdio.h>
int multi_add(int a, int b, int c) {
int d = a * b + c;
return d;
}
\footnotesize \textcolor{pink}{四国めたん:} 関数の宣言等を記述したヘッダーファイルは、最初にインクルードしますわ
\footnotesize \textcolor{lime}{ずんだもん:} 決まりなのか?
\footnotesize \textcolor{pink}{四国めたん:} 決まりではありませんが、自身の関数などを定義したヘッダーファイルは、最初にインクルードするのが一般的ですわね
\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ
\footnotesize \textcolor{pink}{四国めたん:} そして、ヘッダーファイルのファイル名の指定には、山括弧(<>)ではなくダブルクォーテーション("")を使用しますわ
\footnotesize \textcolor{lime}{ずんだもん:} 違いは何なのだ?
\footnotesize \textcolor{pink}{四国めたん:} まず、標準Cライブラリ関係のヘッダーファイルには、括弧(<>)を使いますわ
\footnotesize \textcolor{lime}{ずんだもん:} "stdio.h"などが例なのだ
\footnotesize \textcolor{pink}{四国めたん:} 次に、自作などのヘッダーファイルには、ダブルクォーテーション("")を使いますわ
\footnotesize \textcolor{lime}{ずんだもん:} 標準Cライブラリ関係以外と考えていいのか?
\footnotesize \textcolor{pink}{四国めたん:} その通りですわ
- 標準Cライブラリ関係のヘッダーファイルには山括弧(<>)を使う
- 自作のヘッダーファイルにはダブルクォーテーション("")を使う
\footnotesize \textcolor{pink}{四国めたん:} 次に"hello_world.c"を見てみましょう
#include <stdio.h>
#include "calc.h"
void main() {
int a = 3;
int b = 4;
int c = 5;
int d = multi_add(a, b, c);
printf("積和の答えは%dです。\n", d);
return;
}
\footnotesize \textcolor{pink}{四国めたん:} 関数の宣言等を記述したヘッダーファイルを標準Cライブラリ関係のヘッダーファイルの後にインクルードしますわ
\footnotesize \textcolor{lime}{ずんだもん:} "calc.c"の場合とは順番が違うのだが...
\footnotesize \textcolor{pink}{四国めたん:} ヘッダーファイルをインクルードする順番は決まっていませんわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、ただ、一般的には標準Cライブラリ関系のヘッダーファイルが先ですわ
\footnotesize \textcolor{lime}{ずんだもん:} 唯一の例外が、定義した関数の宣言をしているヘッダーファイルということか
\footnotesize \textcolor{pink}{四国めたん:} はい、ヘッダーファイルは、決められた順番でインクルードすると見やすくなるのでお勧めですわ
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
\footnotesize \textcolor{pink}{四国めたん:} なおVisual Studioでは、関数名にマウスカーソルを合わせるだけでコメントの内容が表示されますわ
\footnotesize \textcolor{lime}{ずんだもん:} それは便利なのだ
ヘッダーファイルには関数の宣言以外も含めます
\footnotesize \textcolor{pink}{四国めたん:} 一般的にヘッダーファイルには関数の宣言を記述しますわ
\footnotesize \textcolor{lime}{ずんだもん:} 他に記述できるものはないのか?
\footnotesize \textcolor{pink}{四国めたん:} 関数の宣言以外にも、ヘッダーファイルに含めると便利なものが色々とありますわ
定数
\footnotesize \textcolor{pink}{四国めたん:} まず、自作の関数の引数として渡すような定数については、ヘッダーファイルに含めると良いとおもいますわ
\footnotesize \textcolor{lime}{ずんだもん:} #define
ディレクティブで定義する定数や列挙体とかか?
\footnotesize \textcolor{pink}{四国めたん:} そうですわね
構造体
\footnotesize \textcolor{pink}{四国めたん:} あと、自作の関数の引数や戻り値の型としての構造体の定義は、ヘッダーファイルに含めると使いやすいですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
まとめ
\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした
\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ
\footnotesize \textcolor{pink}{四国めたん:} 異なるファイルの関数 についての説明は以上ですわ
Discussion