• ベストアンサー

複数ファイルに分割した時の構成について

大学の卒論にむけてプログラムを書いていて、一つのmain.cでは長くなってきたので、関数を func1.h func1.c のような別ファイルに記述することにしました。 その現在の構成を、質問欄の下部に簡単に書いたので、構成が自然かどうか意見をお聞きしたいです。特に、 「include文、define文をヘッダファイルにまとめて、各ファイルからincludeしている構造」がコードの記述方法として、きもちわるくないか、一般的かどうか、教えてください。 このようにした理由は、 ・defineマクロを多くのサブ関数で利用している。 ・define定義の値を細かく変えながら実行し、結果の違いを出力したい。 ・その為、各ファイルの頭にdefine定義を置いた場合、定義の値を  いちいち全てのファイルで変更しなければならなくなり、面倒…。 →defineマクロをdefine.hにまとめた。ついでに、<stdio.h>,<math.h>なども置いてしまえばスッキリするかも~。 という経緯です。 理学の学科でまわりに詳しい人がいなく、 プログラム知識もほぼ独学なので、不安に感じて質問しました。 よろしくおねがいします。 +++++++++++++ 以下が、簡単なファイル構成です +++++++++++++ -----define.h----- #include <stdio.h> #include <math.h> #define A_MAX 3 #define B_MAX 5 -----main.c---- #include "define.h" int main() { func1(); func2(); func3(); } -----func1.h---- #include "define.h" void func1(int hoge); //プロトタイプ宣言 -----func1.c---- #include "func1.h" void func1() { hogehoge; } ------func2以下、func1と同構造

質問者が選んだベストアンサー

  • ベストアンサー
  • goosyu
  • ベストアンサー率58% (36/62)
回答No.2

 このようなヘッダファイルの作成には色々な考え方があるので,一般的な回答は難しいのであくまでも1つの経験的な意見としてお聞きください。  プログラム共通でdefineを使いまわすということであれば,1つのヘッダファイルを作るのは問題ありません。  「define.h」はdefineをまとめて管理するファイルとして定義した場合,共通のヘッダをインクルードするのは矛盾を感じます。ヘッダファイルから元のヘッダファイルとは関係性が低いヘッダファイルをインクルードを行うと,もとのヘッダファイルの定義または意味がぼやけてしまいます。結果的に新しい関数を追加する際に「define.h」の内容を確認しないとCソースファイルに新しくインクルードが必要か判断しないといけなくなります。見た目は「スッキリ」するかもしれません,他人には読みにくいソースコードになります。  また,共通のdefineが必要であっても必ずしも「stdio.h」または「math.h」をインクルードする必要はない場合も考えられ,結果的には無駄なインクルードとなります。無駄なインクルードはコンパイル時間が余計にかかるので小規模の開発では影響が少ないですが,よいことはありません。  開発規模が大きくなるとソースファイルをすべてコンパイルすると数時間というケースがあります。この問題を解決するためには修正したファイルだけをコンパイルして作業効率をあげます。修正したファイルが共通ヘッダファイルであれば,ほぼ全ソースコンパイルとなり効率が悪くなります。この為,変更が考えられるヘッダファイルをまとめることはあまりせず,Cソースコードから必要なヘッダファイルをインクルードさせることが多いです。

minoa_
質問者

お礼

なるほど、勉強になります。 後輩が見ても分かりやすいようにしたいのでその辺も考え、 ご意見を参考にしてファイル構成を修正したいと思います。 ありがとうございました~。

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

#4 ではインクルードガードを define.h に入れるとありますが, func1.h~func3.h にも入れておくべきでしょう. あと, 「define定義の値を細かく変えながら実行し、結果の違いを出力したい。」というなら本当は #define で与えるのではなく, プログラム実行時に引数として値を与えるべきだと思います.

minoa_
質問者

お礼

お返事遅れてすみません。 その値によってデータの数が変わるので、 配列の大きさを変えるためDEFINEを使っていましたが、 仰る通りだと思い、DEFINE定義の大部分を引数に変えました。 配列長のDEFINE定義は残したためdefine.hは結局残りましたが、 意見は参考になりました。 ありがとうございました~。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

空白を含めて全く同じものへの #define だからエラーなどにはならないはずだが.... さておき, main.c で func1.h を #include しないのはなぜ? 「使う前に宣言する」のでなければプロトタイプ宣言の意味がない.

minoa_
質問者

お礼

すみません、質問する際の記述ミスです。。。 本当はmain.cでもfunc{1-3}.hをincludeしています。 失礼致しました。 いろいろ意見を頂いて参考になりましたが、 まだ他の方の異なる意見が伺えるかもしれないので、 もう少しの間、締め切らず残しておきます。 よろしくお願いします。

  • riwity
  • ベストアンサー率58% (7/12)
回答No.4

私は普通にやっているので、おかしくは無いと思います。 しかし、このままでは問題があります。 インクルードガードが無いので、「A_MAXが再定義されています」みたいなエラーが発生するはずです。 対策は下記のどちらかです。ともにdefine.hです。 方法1------------------------------ #pragma once // ~~内容~~ ----------------------------------- 方法2----------------------------- #ifndef DEFINE_H // 文字は任意。 #define DEFINE_H // 二つが同じで他と被らない。 // ~~内容~~ #endif -----------------------------------

minoa_
質問者

お礼

今回の場合エラーは出ていないようですが、 defineなどの再定義を防ぐコーディング手法として勉強になりました。 ご意見のほうも、ありがとうございました。

  • riwity
  • ベストアンサー率58% (7/12)
回答No.3

私は普通にやっているので、おかしくは無いと思います。 しかし、このままでは問題があります。 define.hはその中のマクロを使うクラスのヘッダ全てにincludeしますが、読み込みは一度だけにしましょう。 でなければ「A_MAXが再定義されています」みたいなエラーが発生します。 具体的には下のいづれかをします。ともにdefine.hです。 方法1------------------------------ #pragma once // ~~内容~~ ----------------------------------- 方法2----------------------------- #ifndef DEFINE_H // 文字は任意。 #define DEFINE_H // 二つが同じで他と被らない。 // ~~内容~~ #endif -----------------------------------

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

> void func1(int hoge); //プロトタイプ宣言 > void func1() > { > hogehoge; > } プロトタイプ宣言と、実体で、func1のシグニチャが一致していないのは、まずいかと思われます。

minoa_
質問者

お礼

すみません、質問する際の記述ミスです。。。 失礼いたしました。

関連するQ&A