

No.2ベストアンサー
- 回答日時:
問題ありません。
が、しかし、そのような方法は、実務レベルの場合は、行いません。
以下のような方法をとります。
ファイル名:xxx_ext.c
変数のみを宣言したファイル。
ファイル名:xxx_ext.h
上記の変数のみを宣言したしものをexternで参照するファイル。
ファイル名:func_a.c
関数Aのファイル。
このファイルで、#include xxx_ext.h する
ファイル名:func_b.c
関数Bのファイル。
このファイルで、#include xxx_ext.h する
ファイル名:func_c.c
関数Cのファイル。
このファイルで、#include xxx_ext.h する
上記のようにすることで、externで参照する変数が1つのファイル内に閉じこめられるのでメンテナンス性がよくなります。たとえば、ある理由があって、変数Xの型をintからdoubleに変えることを想定してください。
xxx_ext.c とxxx_ext.hの2つのファイルのみが変更対象
となります。
上記のようにしない場合は、3つのファイル(あるいはそれ以上)を変えることになります。
この回答へのお礼
お礼日時:2005/04/22 20:38
詳しい説明ありがとうございます。今回の場合はxxx_ext.h
はあるのですが、xxx_ext.cがなくて、どこにグローバル変数をおいたらいいか困っていたところです。xxx_ext.cを作ればいいのですが、融通がきかないものでして。。。
No.5
- 回答日時:
No3 ency です。
No4 rentahero さん:
> #3のようにするなら、C++にしてクラスにした方がいいのでは。
確かにそうなんですけどね。
プロジェクトで使用する言語って、個人がどうとか言ってどうになるものでもないですし。。。
# ちなみに、私は組込み系やってます。
# アプリ系は C++ を使ったりしているようですが、下回りはまだまだ
# C から離れられないですね。
# ドライバ屋さんなんかは、アセンブラ使ったりしているところも
# ありますからね。
No4 rentahero さんの参考 URL の方法は、よく見かける方法ですね。
ただ、extern をはずすマクロをどこで define するかという話がありますし、これって結局「どこに定義するべきか?」というのと同じ話になりそうな気がします。
でも、ヘッダファイルとの不整合が発生しにくいという点では、良い方法ですね。
あと、No3 の例で、ヘッダファイルに extern が抜けてますね。。。
# 失礼しました。
この回答へのお礼
お礼日時:2005/04/24 13:25
皆様解答ありがとうございます。最初はグローバル変数は使わないでstatic宣言してget関数set関数をつくって対応するはずだったんですが、関数の数も変えてはいけないことになってしまったもので。。。大変参考になりました。
No.4
- 回答日時:
#3のようにするなら、C++にしてクラスにした方がいいのでは。
まあともかく。
私もグローバル変数を使いたくないのはやまやまなので、私ならそのグローバル変数を使う関数をひとつのファイルにまとめるようにしますね。それならファイルスコープ変数ですみますから。
グローバル変数を使うときのうまいやり方が
Cプログラミング診断室(参考URL参照)に紹介されています。
あと別解として、グローバル変数の代わりに構造体をつくり、mainにてstaticで静的に確保し、各関数にポインタを渡してやればよいのでは?
参考URL:http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.5 …
No.3
- 回答日時:
ファイル分割する際には、機能ごとにファイルを分割すると思います。
で、いくら全体から参照される変数とはいえ、その変数はどこかの機能に属しているはずです。
通常は、その属しているファイルに定義すれば良いと思います。
それで、ファイルスコープの変数定義をしておいて、アクセス用の関数を用意します。
------------------------------------------------
hoge.h
------------------------------------------------
int hoge_get_nantoka( void );
------------------------------------------------
------------------------------------------------
hoge.c
------------------------------------------------
#include "hoge.h"
static int hoge_nantoka;
static void hoge_hoge_kantoka( void );
int hoge_get_nantoka( void )
{
return hoge_nantoka;
}
static void hoge_hoge_kantoka( void )
{
hoge_nantoka = 100;
}
------------------------------------------------
------------------------------------------------
piyo.c
------------------------------------------------
#include "hoge.h"
int piyo_print_nantoka( void )
{
printf( "nantoka=%d\n", hoge_get_nantoka());
}
------------------------------------------------
理由は、他のモジュールから無条件で書き換え可能な変数は作りたくないからです。
# というか、他の人に悪さされたくなかったら、このような設計に
# なってしまうと思います。
複数ファイルから、書き換えが発生するグローバル変数は極力避けたほうが良いと思います。
# 現実的に無理な場合もあるでしょうけど、そのような場合には
# ファイル分割の仕方を見直すべきだと思います。
いわゆる「カプセル化」ってやつですね。
オブジェクト指向でなくても、このようなことは複数人で運営しているプロジェクトなら、当たり前のようにやっていると思います。
# 知らない人に、知らないところで、実は変数書き換えられていました、
# なんてことを起こさないためにもね。
さて、そうはいってもモジュールが機能追加等でだんだん大きくなってきて、同じモジュールでもファイル分割をする必要が出てくることもあるでしょう。
その場合、ヘッダファイルもモジュール内部用のヘッダファイルと、モジュール外用のいわゆる公開ヘッダファイルに分割すると良いでしょう。
------------------------------------------------
hoge.h
------------------------------------------------
/* 公開ヘッダファイル */
int hoge_get_nantoka( void );
------------------------------------------------
------------------------------------------------
hoge_prv.h
------------------------------------------------
/* hoge のプライベートヘッダファイル */
/* 公開ヘッダファイルはインクルードしておく*/
#include "hoge.h"
int hoge_nantoka;
void hoge_hoge_kantoka( void );
------------------------------------------------
------------------------------------------------
hoge_a.c
------------------------------------------------
/* プライベートヘッダファイルをインクルードする */
#include "hoge_prv.h"
int hoge_get_nantoka( void )
{
return hoge_nantoka;
}
------------------------------------------------
------------------------------------------------
hoge_b.c
------------------------------------------------
/* プライベートヘッダファイルをインクルードする */
#include "hoge_prv.h"
void hoge_hoge_kantoka( void )
{
hoge_nantoka = 100;
}
------------------------------------------------
------------------------------------------------
piyo.c
------------------------------------------------
/* hoge の公開ヘッダファイルをインクルードする */
#include "hoge.h"
int piyo_print_nantoka( void )
{
printf( "nantoka=%d\n", hoge_get_nantoka());
}
------------------------------------------------
このようにしておけば、万が一他のモジュールからのアクセスがあった場合、運がよければエラーをはいてくれますし、最悪でも警告は出してくれるはずです。
# ヘッダファイルの中でヘッダファイルをインクルードすることに対する
# 賛否はあるようですけど、私はこうしています。
ま、話が本来の趣旨とは関係ない方向に行ってしまいましたが。。。
これがふつうだと思っていたんだけど、どうなんでしょうかねぇ。。。
# 誰に教わったとか言うんじゃないけど、実運用上こうしないと
# 余計なバグの温床になりかねないと思いますし。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
同じ型【ハイフンと数字】だけ...
-
HTTPSのとき":"が"%3A"ではなく...
-
Vb.netのグローバル変数の宣言...
-
ボタンをクリックすると数が増...
-
【正規表現】【javascript】CR...
-
hoge の謎
-
MFCのキャプション変更
-
構造体を引数で関数へ渡す
-
JavaScriptで書き出したオート...
-
ActiveXobjectが作成できない
-
C#OpenCv V4にのエラーに関する...
-
jspからjavascriptの変数引継ぎ
-
jslintのエラーについて質問
-
JavaScriptで平日のみをカウン...
-
問題の個数を数える。
-
同じIDで定義した要素の配列を...
-
ローカルにあるファイルを検索...
-
四肢麻痺の娘のパソコンの使い方
-
javascriptで編集可能不可能の...
-
C#テキストボックスの文字を配...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ボタンをクリックすると数が増...
-
【正規表現】【javascript】CR...
-
同じ型【ハイフンと数字】だけ...
-
ASP+アクセスでのSQLコメントに...
-
サブウインドウから親ウインド...
-
HTTPSのとき":"が"%3A"ではなく...
-
confirmの連続?
-
VC++のちらつき防止方法
-
Boolean型配列中のTrueの有無を...
-
Vb.netのグローバル変数の宣言...
-
javascriptで文字挿入でtoggle...
-
コールバック関数(?)をループし...
-
【Jquery】changeイベント毎にa...
-
ifreamをリロードしたい
-
Excel VBA の ChangeFileAccess
-
MFCのキャプション変更
-
Linux バイナリ実行できない "...
-
-(ハイフン)_(アンダーバー)の...
-
2次元のJSON形式の配列の展開
-
C# .NET DataGridView の行を追...
おすすめ情報