広告
↓発売日:2018年09月22日↓
新品価格 |
今回はソースの分割をやっていきたいと思います。
これができれば大きなプログラムもソースを分ける事によってすっきり見やすくなりますね!
前半はあまりよろしくない分割の仕方も中には含まれているので、ひとまずはそのように分割できるという事を学んでください。
後半にいくぶんマトモ?な分割の仕方をご紹介します。
/*十一日目 プログラム1*/ #include <stdio.h> void hello_world(void); int main(){ hello_world(); return 0; } void hello_world(){ printf("hello world\n"); }
「hello_world」という関数が「hello world」するだけのプログラムです。
まずはこのプログラムを分割してみます。
では一番シンプルな分割として関数の部分だけ分けてみましょう!
下準備として新しくソースファイルを追加します。
一番最初にソースファイルを作成した時と同じ手順で
右側のソリューションエクスプローラー内のソースファイルを右クリック→追加→新しい項目を選んで
「.cpp」ファイルを追加します。
いちよう名前が混同しないように「hello_world.cpp」という名前にしておきました。
「場所」の部分はそのままいじらないで大丈夫です。
もともとあるソースファイルの名前も右クリック→名前の変更で「main.cpp」という名前に変更しておきました。
それでは分割をしていきます。
/*十一日目 プログラム2その1*/ #include <stdio.h> void hello_world(void); int main(){ hello_world(); return 0; }
/*十一日目 プログラム2その2*/ #include <stdio.h> void hello_world(){ printf("hello world\n"); }
これで分割完了しました。
関数本体の部分だけを移動しただけという感じですね。
なんだ簡単じゃん!と思われるかもしれませんが大事な点がいくつかあります。
「main.cpp」の方にプロトタイプ宣言が必要になります。
これを書く事によって「void hello_world(void)」という関数がどこかにありますよ!と示す事になります。
いつものヘッダファイルが両方のファイルに書かれておりますが、これはとりあえず全てのファイルに書いておけばいいというものではありません。
あくまでも必要なので書いております。
試しに「#include <stdio.h>」を消してみると、
「printf()」関数の部分に警告が現れるのが確認できるかと思います。
今まで一つのソースファイルだけでプログラムを組んでいたので、「意味はわからないけどとりあえず書いとけばいいやー!」ですましていた事もこれからは通用しません。
関数や命令一つ一つを噛みしめながらプログラムを書いていきましょう!
※正確に言いますと今回の場合は「main.cpp」の方の「#include <stdio.h>」は必要ないのですが、なんとなくサマにならないので記述しております。
複数の関数を書く事も可能です。
/*十一日目 プログラム3その1*/ #include <stdio.h> void hello_world(void); void goodby_world(void); void thankyou_world(void); int main(){ hello_world(); goodby_world(); thankyou_world(); return 0; }
/*十一日目 プログラム3その2*/ #include <stdio.h> void hello_world(){ printf("hello world\n"); } void goodby_world(){ printf("goodby world\n"); } void thankyou_world(){ printf("thankyou world\n"); }
別に一つのファイルに一つの関数というワケではなく、同じ手順で複数の関数を記述する事ができます。
さらに分割された方のファイルにプロトタイプ宣言を書いて、また他に用意した方のファイルに本体を書く事もできます。
新しく「hello_world2.cpp」というソースファイルを追加しております。
/*十一日目 プログラム4その1*/ #include <stdio.h> void hello_world(void); int main(){ hello_world(); return 0; }
/*十一日目 プログラム4その2*/ #include <stdio.h> void goodby_world(void); void thankyou_world(void); void hello_world(){ printf("hello world\n"); goodby_world(); thankyou_world(); }
/*十一日目 プログラム4その3*/ #include <stdio.h> void goodby_world(){ printf("goodby world\n"); } void thankyou_world(){ printf("thankyou world\n"); }
ややこしくなるのでこのような分割の仕方はあまりする事はないと思いますが、これでプロトタイプ宣言が「int main()」になくてはならないというワケではない事がわかりますね!
ただ、この状態で「main.cpp」から直接「goodby_world()」関数や「thankyou_world()」関数を読み出そうとしても、プロトタイプ宣言がないので呼び出す事はできません。
広告
ここまでの分割の仕方だけでも小規模なプログラムなら対応できそうですが、中規模、それ以上のプログラムともなると「int main()」もしくは関数本体が書いてあるファイルに混同してプロトタイプ宣言がずらずらと並んでいるのはあまりよろしくない気がしますよね。
そこでヘッダファイルというものを使います。
いつも先頭に書いている「#include <stdio.h>」みたいなのを自分でも作ろうというワケです。
ヘッダファイル、その役割はプロトタイプ宣言、構造体変数宣言、定数宣言、などなど主に宣言にあたいするものをここには書いていきます。
という事は今まで「int main()」などに書いていた分割した関数のプロトタイプ宣言、あれも本来はこちらに書いていくという事なんですね。
なので関数本体があるファイル、そのプロトタイプ宣言があるヘッダファイルを対になるようなカタチで作っていきます。
下準備として同じような手順で今度はヘッダファイルを追加してください。
右側のソリューションエクスプローラー内のヘッダファイルを右クリック→追加→新しい項目を選んで
ヘッダファイルを追加します。
名前は「hello_world.h」にしました。
名前もその関数本体に合うようにつけます。
ヘッダファイルを追加したときに最初から「#pragma once」という一文が書いてある場合はそのまま消さないでその下からプログラミングしていってください。
「#pragma once」については次回説明します。
それではヘッダファイルも含めた分割をしていきます。
/*十一日目 プログラム5その1*/ #include <stdio.h> #include "hello_world.h" int main(){ hello_world(); goodby_world(); thankyou_world(); return 0; }
/*十一日目 プログラム5その2*/ void hello_world(void); void goodby_world(void); void thankyou_world(void);
/*十一日目 プログラム5その3*/ #include <stdio.h> void hello_world(){ printf("hello world\n"); } void goodby_world(){ printf("goodby world\n"); } void thankyou_world(){ printf("thankyou world\n"); }
これでプロトタイプ宣言もまとめる事ができてスッキリしましたね!
「main.cpp」の先頭で
#include "hello_world.h"
今作ったヘッダファイルをインクルードする事によりその中の関数群を使えるようになります。
自作ヘッダは「"」で囲むトコロに注意です。
自作ヘッダも作れるようになったトコロで「#include」するとはどういう事なのかを今一度考えてみます。
今まではファイルを取り込むみたいな言い方をしてきたので、何かスゴイ事をしているようなイメージのある「#include」ですが、実を言いますとこの命令はその指定されたファイルの内容をペタっと貼り付けているにすぎません。
たとえば先ほどの例で言いますと
#include <stdio.h> #include "hello_world.h" int main(){ hello_world(); goodby_world(); thankyou_world(); return 0; }
この「#include "hello_world.h"」と記述された部分にその内容を貼り付けているだけなので
#include <stdio.h> /*#include "hello_world.h"の内容を*/ /*↓貼り付け↓*/ void hello_world(void); void goodby_world(void); void thankyou_world(void); int main(){ hello_world(); goodby_world(); thankyou_world(); return 0; }
こんな感じの事をしているだけなのです。
ここで勘違いしないで頂きたいのが、あくまでも貼り付けられているのはその指定されたヘッダファイルの内容というだけであって、その本体にあたる
「hello_world()」
「goodby_world()」
「thankyou_world()」
は別のファイルのままというトコロに注意してください。
次回グローバル変数の扱い方や2重定義を防ぐインクルードガードというものを扱うにあたりここを勘違いしたままだとけっこうハマります!!!
「インクルードして貼り付けられているだけの部分」と「別のファイルに分かれている部分」の違いに気をつけましょう!
構造体変数宣言、定数宣言などをヘッダファイルに分割した例です。
/*十一日目 プログラム6その1*/ #include <stdio.h> #include "my_header.h" int main(){ struct PLAYER p; int ary[HEIGHT][WIDTH] = { {9,9,9,9,9,9,9,9,9,9}, {9,0,0,0,0,0,0,0,0,9}, {9,0,9,9,9,9,9,9,9,9}, {9,0,0,0,0,0,0,0,0,9}, {9,9,9,9,0,9,9,9,0,9}, {9,0,9,0,0,0,0,0,0,9}, {9,0,9,9,9,9,9,9,0,9}, {9,0,0,0,0,0,9,0,0,9}, {9,0,9,9,0,0,0,0,9,9}, {9,9,9,9,9,9,9,9,9,9}, }; int x,y; p.x = 1; p.y = 8; ary[p.y][p.x] = 1; for(y=0;y<HEIGHT;y++){ for(x=0;x<WIDTH;x++){ if(ary[y][x] == 9){ printf("□"); } else if(ary[y][x] == 1){ printf("P"); } else{ printf(" "); } } printf("\n"); } return 0; }
/*十一日目 プログラム6その2*/ #include "define.h" #include "struct.h"
/*十一日目 プログラム6その3*/ #define WIDTH 10 #define HEIGHT 10
/*十一日目 プログラム6その4*/ struct PLAYER{ int x; int y; };
このようにヘッダファイルをまとめたヘッダファイルを作ってそれをインクルードするようなやり方もあります。
ヘッダファイルやプロトタイプ宣言の意味を確認しながらいろいろ試してみてください。
それでは次回は分割したソースファイル同士での変数の受け渡しなどを見ていきたいと思います。
広告
↓発売日:2016年02月29日↓
12歳からはじめる ゼロからのC言語 ゲームプログラミング教室 新品価格 |
↓発売日:2018年06月22日↓
新品価格 |
↓発売日:2018年03月09日↓
新品価格 |
↓発売日:2017年06月14日↓
新品価格 |
↓発売日:2018年05月21日↓
新品価格 |
↓発売日:2017年12月07日↓
新品価格 |
↓発売日:2017年02月08日↓
新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ) 新品価格 |
↓発売日:2017年09月26日↓
新品価格 |