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つのファイル(あるいはそれ以上)を変えることになります。
詳しい説明ありがとうございます。今回の場合は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 が抜けてますね。。。
# 失礼しました。
皆様解答ありがとうございます。最初はグローバル変数は使わないで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で質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- その他(Microsoft Office) 【スプレドシート】IMPORTRANGE関数とSUMIFSの組み合わせ 1 2023/03/05 18:17
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- Windows 10 Windows10で、フォルダにあるすべてのファイルを、下層フォルダも含め一つの階層へ配置し直したい 3 2022/05/31 09:50
- Excel(エクセル) Indirect関数について、Formulatextで抽出した数式を参照したい。 1 2022/12/15 11:16
- C言語・C++・C# プログラム内から、MIDIファイルの一部分だけを再生する方法 1 2023/02/15 11:08
- C言語・C++・C# 競技プログラミングに関する質問です。 3 2022/04/03 19:51
- その他(社会・学校・職場) 誰か聞いてください。 社会人6年目ですが、私はポンコツすぎますか? 上司にとあるAファイルの数式を全 1 2023/08/10 18:25
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excel VBA の ChangeFileAccess
-
プログラミングのペーパーテス...
-
Boolean型配列中のTrueの有無を...
-
ifreamをリロードしたい
-
【正規表現】【javascript】CR...
-
ASP+アクセスでのSQLコメントに...
-
MFCのキャプション変更
-
Linux バイナリ実行できない "...
-
ボタンをクリックすると数が増...
-
HTTPSのとき":"が"%3A"ではなく...
-
「オブジェクトが必要です。」...
-
『名前空間』の意味を教えてく...
-
onclick指定関数の引数へローカ...
-
System::Drawing::Color::XXXX...
-
C# .NET DataGridView の行を追...
-
Option Strictと構造体とArrayL...
-
サーバの、クライアント間でデ...
-
VB.NETで変数の型は自作...
-
PDFファイルをWEB上で見れるよ...
-
複数ファイルで使うグローバル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Boolean型配列中のTrueの有無を...
-
Linux バイナリ実行できない "...
-
ASP+アクセスでのSQLコメントに...
-
「オブジェクトが必要です。」...
-
Excel VBA の ChangeFileAccess
-
static constメンバ変数(配列)...
-
【Jquery】changeイベント毎にa...
-
HTTPSのとき":"が"%3A"ではなく...
-
【正規表現】【javascript】CR...
-
C# .NET DataGridView の行を追...
-
サブウインドウから親ウインド...
-
Vb.netのグローバル変数の宣言...
-
ボタンをクリックすると数が増...
-
MFCのキャプション変更
-
Perlから送信するメールのヘッ...
-
正規表現で半角数字1桁のみを全...
-
Imageコントロール vba
-
Option Strictと構造体とArrayL...
-
Javascriptグローバル変数の値...
-
関数を呼び出すHTMLタグ<body o...
おすすめ情報