プロが教えるわが家の防犯対策術!

大学の卒論にむけてプログラムを書いていて、一つの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と同構造

A 回答 (6件)

 このようなヘッダファイルの作成には色々な考え方があるので,一般的な回答は難しいのであくまでも1つの経験的な意見としてお聞きください。


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

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

お礼日時:2009/09/21 18:56

#4 ではインクルードガードを define.h に入れるとありますが, func1.h~func3.h にも入れておくべきでしょう.


あと, 「define定義の値を細かく変えながら実行し、結果の違いを出力したい。」というなら本当は #define で与えるのではなく, プログラム実行時に引数として値を与えるべきだと思います.
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/09/29 22:48

空白を含めて全く同じものへの #define だからエラーなどにはならないはずだが....


さておき, main.c で func1.h を #include しないのはなぜ? 「使う前に宣言する」のでなければプロトタイプ宣言の意味がない.
    • good
    • 0
この回答へのお礼

すみません、質問する際の記述ミスです。。。
本当はmain.cでもfunc{1-3}.hをincludeしています。
失礼致しました。

いろいろ意見を頂いて参考になりましたが、
まだ他の方の異なる意見が伺えるかもしれないので、
もう少しの間、締め切らず残しておきます。
よろしくお願いします。

お礼日時:2009/09/21 19:14

私は普通にやっているので、おかしくは無いと思います。


しかし、このままでは問題があります。

インクルードガードが無いので、「A_MAXが再定義されています」みたいなエラーが発生するはずです。
対策は下記のどちらかです。ともにdefine.hです。

方法1------------------------------
#pragma once
// ~~内容~~
-----------------------------------
方法2-----------------------------
#ifndef DEFINE_H // 文字は任意。
#define DEFINE_H // 二つが同じで他と被らない。
// ~~内容~~
#endif
-----------------------------------
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/09/21 19:07

私は普通にやっているので、おかしくは無いと思います。


しかし、このままでは問題があります。

define.hはその中のマクロを使うクラスのヘッダ全てにincludeしますが、読み込みは一度だけにしましょう。
でなければ「A_MAXが再定義されています」みたいなエラーが発生します。
具体的には下のいづれかをします。ともにdefine.hです。

方法1------------------------------
#pragma once
// ~~内容~~
-----------------------------------
方法2-----------------------------
#ifndef DEFINE_H // 文字は任意。
#define DEFINE_H // 二つが同じで他と被らない。
// ~~内容~~
#endif
-----------------------------------
    • good
    • 0

> void func1(int hoge); //プロトタイプ宣言


> void func1()
> {
> hogehoge;
> }
プロトタイプ宣言と、実体で、func1のシグニチャが一致していないのは、まずいかと思われます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/09/21 19:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!