
以下のようなプログラムを組んでいます。
//main.h
static int hoge;
void someOperation();
//hoge.cpp
#include "main.h"
extern int hoge;
void someOperation()
{
hoge = 15;
}
//main.cpp
#include <stdio.h>
#include "main.h"
extern int hoge;
int main()
{
someOperation();
printf("%d\n",hoge);
return 0;
}
このプログラムを実行したのですが、自分の予想した15という出力ではなく、不定値になるようなのです。
自分の予想では、someOperationで操作するhogeも、main内で操作するhogeも同じになるようにと思いexternをつけているのですが、なにがまずいのでしょうか?
ご存知の方、ご教授お願いします。

No.1ベストアンサー
- 回答日時:
結論から言えば、
static int hoge;
で、static をつけてはいけません。
この場合、hoge.cpp と main.cpp のどちらか一方に、
int hoge;
他方に、
extern int hoge;
が必要になります。
これを一括管理するテクニックとしては、以下のようなものが紹介されていました。
main.h
#if defined(GLOBAL_HERE)
#define EXT
#define DEF(x) = (x)
#else
#define EXT extern
#define DEF(x)
#endif
EXT int hoge;
main.cpp
#define GLOBAL_HERE
// この後で、inlude すると、EXT 指定した変数は、実態が宣言される
#include "main.h"
hoge.cpp
// こちらでは(ほかのファイルでも) GLOBAL_HERE は定義しない
#include "main.h"
// こちらでは、EXT 指定した変数は、 extern と読み替えられる
初期化が必要なときには、
EXT int hog DEF(10);
などとすると、
#define GLOBAL_HERE
のあとで include された場合は、
int hoge = (10);
そうでない場合には、
extern int hoge;
となります。
No.2
- 回答日時:
★まずいですね。
・まず main.h のヘッダファイルに static int hoge という変数の実体があります。
結論から言うとこのような記述は避けるべきなのです。
理由は
・hoge.cpp で main.h をインクルードしていますが、ここで hoge.cpp でしか使えない
static int hoge が実体として作られます。これに 15 を代入していますが、static キーワードが
付いているので他のソースファイル(main.cpp)からアクセスできません。見えないので。
・また main.cpp でも main.h をインクルードしていますが、こんどは main.cpp 用でしか使えない
static int hoge が実体として作られます。つまり2つの hoge 変数が存在します。
・main.cpp では、この自分で見える hoge=0 が表示されます。
決して hoge.cpp の hoge 変数ではありません。注意。
// hoge.cpp
static int hoge=15; ←main.cpp からは参照できない(隠されている)
// main.cpp
static int hoge=0; ←main.cpp ではこれを表示している
※hoge がそれぞれのソースファイルに1つずつ作られて合計2つあります。
解決策:
・main.h ヘッダには extern int hoge; のプロトタイプ宣言だけをします。
そして hoge.cpp に extern int hoge=0; と定義します。
そして someOperation() 関数内で hoge=15; とします。
・main.cpp では main.h をインクルードしますので『extern int hoge;』の
記述は必要ありません。→あっても問題はありませんけど。
//main.h
extern int hoge;
void someOperation();
//hoge.cpp
#include "main.h"
extern int hoge = 0; ←※かならず何かの値を代入すること
void someOperation()
{
hoge = 15;
}
//main.cpp
#include <stdio.h>
#include "main.h"
int main( void )
{
someOperation();
printf( "%d\n", hoge );
return 0;
}
以上。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- C言語・C++・C# プログラミングのペーパーテスト 実行結果がどのように表示されるか答えよ #include <stdi 1 2022/07/09 14:27
- C言語・C++・C# プログラミングの授業のペーパーテスト 実行結果を答えろ #include int x[ ] = {1 3 2022/06/16 20:08
- C言語・C++・C# プログラミングペーパーテスト 次の問題の実行結果を答えろ #include int x[ ] = { 1 2022/06/16 21:49
- C言語・C++・C# 至急教えてください! プログラミングの問題です! お願いします! 出力2と全く同じ出力をするように、 2 2022/06/22 23:10
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語 5 2023/04/27 13:20
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# プログラミングを教えて欲しいです。 配列aは、int a[9]={7,6,12,8,3,5,10,9 4 2022/12/19 23:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ボタンをクリックすると数が増...
-
HTTPSのとき":"が"%3A"ではなく...
-
responseTextを使っての書き換...
-
Boolean型配列中のTrueの有無を...
-
Linux バイナリ実行できない "...
-
jQuery 変数を複数のセレクタ...
-
【Jquery】changeイベント毎にa...
-
static constメンバ変数(配列)...
-
class指定したHTML要素の背景色...
-
return (A && B) || 0;
-
static と externについて
-
全部のアクセスを指定したペー...
-
【正規表現】【javascript】CR...
-
ASP+アクセスでのSQLコメントに...
-
バイナリファイルから文字列を...
-
System::Drawing::Color::XXXX...
-
Double→Integerへの変換で「意...
-
アンカーリンクをクリックさせ...
-
プルダウンメニューをmouseout...
-
「オブジェクトが必要です。」...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
HTTPSのとき":"が"%3A"ではなく...
-
ボタンをクリックすると数が増...
-
【正規表現】【javascript】CR...
-
Boolean型配列中のTrueの有無を...
-
Linux バイナリ実行できない "...
-
ASP+アクセスでのSQLコメントに...
-
Excel VBA の ChangeFileAccess
-
Vb.netのグローバル変数の宣言...
-
static constメンバ変数(配列)...
-
同じ型【ハイフンと数字】だけ...
-
javascriptで文字挿入でtoggle...
-
アンカーリンクをクリックさせ...
-
VC++のちらつき防止方法
-
C# .NET DataGridView の行を追...
-
MFCのキャプション変更
-
hoge の謎
-
confirmの連続?
-
return (A && B) || 0;
-
ifreamをリロードしたい
-
-(ハイフン)_(アンダーバー)の...
おすすめ情報