大学の卒論にむけてプログラムを書いていて、一つの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と同構造
No.2ベストアンサー
- 回答日時:
このようなヘッダファイルの作成には色々な考え方があるので,一般的な回答は難しいのであくまでも1つの経験的な意見としてお聞きください。
プログラム共通でdefineを使いまわすということであれば,1つのヘッダファイルを作るのは問題ありません。
「define.h」はdefineをまとめて管理するファイルとして定義した場合,共通のヘッダをインクルードするのは矛盾を感じます。ヘッダファイルから元のヘッダファイルとは関係性が低いヘッダファイルをインクルードを行うと,もとのヘッダファイルの定義または意味がぼやけてしまいます。結果的に新しい関数を追加する際に「define.h」の内容を確認しないとCソースファイルに新しくインクルードが必要か判断しないといけなくなります。見た目は「スッキリ」するかもしれません,他人には読みにくいソースコードになります。
また,共通のdefineが必要であっても必ずしも「stdio.h」または「math.h」をインクルードする必要はない場合も考えられ,結果的には無駄なインクルードとなります。無駄なインクルードはコンパイル時間が余計にかかるので小規模の開発では影響が少ないですが,よいことはありません。
開発規模が大きくなるとソースファイルをすべてコンパイルすると数時間というケースがあります。この問題を解決するためには修正したファイルだけをコンパイルして作業効率をあげます。修正したファイルが共通ヘッダファイルであれば,ほぼ全ソースコンパイルとなり効率が悪くなります。この為,変更が考えられるヘッダファイルをまとめることはあまりせず,Cソースコードから必要なヘッダファイルをインクルードさせることが多いです。
なるほど、勉強になります。
後輩が見ても分かりやすいようにしたいのでその辺も考え、
ご意見を参考にしてファイル構成を修正したいと思います。
ありがとうございました~。
No.6
- 回答日時:
#4 ではインクルードガードを define.h に入れるとありますが, func1.h~func3.h にも入れておくべきでしょう.
あと, 「define定義の値を細かく変えながら実行し、結果の違いを出力したい。」というなら本当は #define で与えるのではなく, プログラム実行時に引数として値を与えるべきだと思います.
お返事遅れてすみません。
その値によってデータの数が変わるので、
配列の大きさを変えるためDEFINEを使っていましたが、
仰る通りだと思い、DEFINE定義の大部分を引数に変えました。
配列長のDEFINE定義は残したためdefine.hは結局残りましたが、
意見は参考になりました。
ありがとうございました~。
No.5
- 回答日時:
空白を含めて全く同じものへの #define だからエラーなどにはならないはずだが....
さておき, main.c で func1.h を #include しないのはなぜ? 「使う前に宣言する」のでなければプロトタイプ宣言の意味がない.
すみません、質問する際の記述ミスです。。。
本当はmain.cでもfunc{1-3}.hをincludeしています。
失礼致しました。
いろいろ意見を頂いて参考になりましたが、
まだ他の方の異なる意見が伺えるかもしれないので、
もう少しの間、締め切らず残しておきます。
よろしくお願いします。
No.4
- 回答日時:
私は普通にやっているので、おかしくは無いと思います。
しかし、このままでは問題があります。
インクルードガードが無いので、「A_MAXが再定義されています」みたいなエラーが発生するはずです。
対策は下記のどちらかです。ともにdefine.hです。
方法1------------------------------
#pragma once
// ~~内容~~
-----------------------------------
方法2-----------------------------
#ifndef DEFINE_H // 文字は任意。
#define DEFINE_H // 二つが同じで他と被らない。
// ~~内容~~
#endif
-----------------------------------
今回の場合エラーは出ていないようですが、
defineなどの再定義を防ぐコーディング手法として勉強になりました。
ご意見のほうも、ありがとうございました。
No.3
- 回答日時:
私は普通にやっているので、おかしくは無いと思います。
しかし、このままでは問題があります。
define.hはその中のマクロを使うクラスのヘッダ全てにincludeしますが、読み込みは一度だけにしましょう。
でなければ「A_MAXが再定義されています」みたいなエラーが発生します。
具体的には下のいづれかをします。ともにdefine.hです。
方法1------------------------------
#pragma once
// ~~内容~~
-----------------------------------
方法2-----------------------------
#ifndef DEFINE_H // 文字は任意。
#define DEFINE_H // 二つが同じで他と被らない。
// ~~内容~~
#endif
-----------------------------------
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAを何回も作り直して、容量が...
-
<math.h>があるのにsqrtが・...
-
C言語でヘッダファイルにグロー...
-
C++コンパイル時に『 C1083: in...
-
「fatal error C1189」を回避す...
-
マクロ コンパイルがグレーバック
-
セミコロンについて
-
クリティカルエラー Expressio...
-
cygwin でstackdump
-
構造体をファイルに出力できません
-
1 つ以上の複数回定義されてい...
-
【VC++6.0(MFC)】警告「LINK : ...
-
コンパイルエラー:ユーザ定義...
-
C言語でmからnまでの合計を求め...
-
ビルドとリビルドの違いを教え...
-
sys/types.hの必要性について
-
” OS ビルド ” の意味が分か...
-
PRO*C コンパイルエラー
-
外部シンボル "_main"は未解決です
-
FindFirstFileについて教えてく...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAを何回も作り直して、容量が...
-
<math.h>があるのにsqrtが・...
-
” OS ビルド ” の意味が分か...
-
1 つ以上の複数回定義されてい...
-
「fatal error C1189」を回避す...
-
ILSpyで、デコンパイルできない。
-
Makefile作成時の拡張子.oとは?
-
エクセルVBAではRound...
-
C言語でヘッダファイルにグロー...
-
外部シンボル "_main"は未解決です
-
セミコロンについて
-
マクロ コンパイルがグレーバック
-
戻り値について
-
C言語でmからnまでの合計を求め...
-
C++コンパイル時に『 C1083: in...
-
コンパイルエラー:ユーザ定義...
-
クリティカルエラー Expressio...
-
PRO*C コンパイルエラー
-
【VC++6.0(MFC)】警告「LINK : ...
-
[c++] <pthread.h>がinclude で...
おすすめ情報