• ベストアンサー

Static変数の必然性について

 今晩は、Cの初心者です、宜しくお願いします。    Global変数とStatic変数の違いがよく分かりせん。  本を読むと、Global変数は「常に同じメモリ上に置かれどの関数からも使用できる」、Static変数は「常に同じ メモリ上に置かれ定義された関数からのみ使用できる」とかいています。  Global変数がどのようなもので、その必要性みたいなものは理解出来るのですが、Static変数については、 Global変数との違い、その必要性、実際にどのような場合に使うのかその必然性みたいものがあるのか理解できません。  いくら本を読んでも、理解出来ないのですが、宜しくご教示願います。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

参考リンクより引用 「Cで扱うメモリ領域は一般に、プログラム領域、静的領域、  スタック領域、ヒープ領域の 4つに大別されます。」 まず明かな違いとしてグローバル変数はスタック領域、static変数は静的領域に確保されますのでメモリの位置が異なります。 実用上の問題としては全ての変数をグローバルで扱うならstatic変数はいりませんが、一般的にグローバル変数は多用厳禁とされています。 なのでローカルに置いた方が分かりやすく、かつ変数の値を残したい場合に必要になってきます。 実際は構造体を組む時なんかに便利な機能です。 2人協力プレーの出来るゲームで魔力ゲージを共有するような場合、こんな感じで組めます。 struct Character{ int HP; //体力 static int MP; //魔力、全キャラで共有 int Attack; //攻撃力 int Guard; //防御力 int Score; //得点 //必要に応じて変数を追加していく }; void main(){ Chaacter a,b; //自機はaとbの2体 //以下略 }

参考URL:
http://www9.plala.or.jp/sgwr-t/c/sec12.html

その他の回答 (2)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

関数内でしか使わない変数は関数内で宣言しましょうということです いいかえれば1個の関数でしか使わない変数をグローバル変数にしない

htgotk_001
質問者

お礼

みなさん、回答有り難うございました。 もう少し自分でも勉強してみます。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

Global(=大域的)というのは有効範囲や結合の話であり、Static(=静的)というのは記憶域期間の話です。 まったく別の概念ですので、行動してはいけません。 それぞれを一言で説明するのは難しいので、自分で検索してみてください。 検索に必要なキーワードは上記説明に盛り込んでいます。

関連するQ&A

  • Java main関数内でStatic変数使えない

    JavaのStatic変数について質問です。 Main関数の中でStaticな変数を定義しようとしたところ、 final修飾子しか使えませんというエラー文言が出ます。 Main関数内でわざわざStatic変数を使用する必要はないのですが、 出来ないと言われると何故だろうと思ってしまいます。 どなたかご説明いただけないでしょうか? -------------------------------------------------------------------- class Test { public static void main(String[] args) { // 宣言時Staticは使えなく、finalでしか定義できないとエラーが出る Static int test_val = 10; // 表示 System.out.println(test_val); } }

    • ベストアンサー
    • Java
  • 関数内、ファイルのstatic変数

    関数内で、static変数を宣言した場合に、その値は保持されると 思いますが、その関数の外からポインタで見る場合にその値は 保証されるのでしょうか? (必ず同じメモリ上に配置されるのでしょうか?) また、関数とファイル内static変数においてスコープ以外に 取り扱いが変わったりするのでしょうか? (配置されるメモリ空間等) よろしくお願い致します。

  • C言語のStatic変数について

    現在、C言語の勉強しながらゲームプログラムにチャレンジしています。 二つの関数で利用する変数を作りたかったので、Static宣言された変数を容易しました。 ですが、この変数、一度処理が終わると当面使わない変数なのです。 (ただし、処理途中は何度も呼び出されるので値は保持しなければいけません) よって、メモリ上に延々居座られるのが邪魔に思えて仕方ありません。 実際、大したことないだろうとは思うのですが。 このStaticで宣言された変数を、自分の好きなタイミングでメモリ上から解放するような処理はできませんか? もしくはメモリ上に居座ることのない処理の仕方などありましたら、 考え方を教えていただけるとうれしいです。よろしくお願いします。

  • 関数外からstatic変数を再度初期化できるのでしょうか?

    以下の静的変数?についてA,Bのメモリは別でしょうか? test関数外からBの変数を再度初期化できるのでしょうか? staticの仕組みがわからないのでstaticのメモリの初期化のタイミングとメモリアクセス方法について知りたいです。 static x = 1; // ---A int test() { static int x = 0; // --- B } またexternの働きも知りたいです。

  • staticの動作について

    C++で趣味でゲームを作っているのですが、staticを使ったときのローカル変数の動作について質問があります。 いまいち、ローカル変数の動作が分かっていないのですが、大雑把には、関数が読み出される毎に空いてるメモリを探して、そこを確保する物だと思ってます。 で、staticを用いて宣言すると内容が保持されると言うことは、これは始めに一回だけメモリの確保をして、以降はそれを継続して使っているというものなのでしょうか? だとすると、staticをつかったローカル変数の方が、繰り返しメモリの確保が行われ無い分、処理が早いということでしょうか? いま、ゲーム内では、描画用の関数描画基準座標とサイズを受け渡して入るのですが、どうしても内部で描画終了点と開始点のクリップを計算する必要があり、そのためにどうしても計算した開始点、終了点を保持する変数が必要になっています。 しかし、描画関数はキャラの分と背景描画の分とパーティクルの描画の分と、ゲーム1ループないでも1000回近く(多いときは2000回ぐらい)呼び出されてます。 その度にメモりの確保をされるのはなんか気分が悪いなぁと思ってstaticを何となくつているのですが、実際の所staticを着けたら動作がはやくなるとかと言うことは無いのでしょうか? 宜しくおねがします。

  • クラス内の関数内static変数について

    クラス内の「staticではないメンバ関数内で定義される」static変数の初期化タイミングはいつでしょうか? 自分としてはクラスのインスタンス生成時に初期化されるものだと思っていたのですが、どうもそうでは無さそうだという現象に出会ったもので。 例えば以下のようなサンプルプログラムがあるとします。 --------------------------------------- class TA { public: void func(int i); }; void TA::func(int i) { static int d=0; d += i; std::cout << d << std::endl; } int main() { for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); } } --------------------------------------- これを実行した時、自分としては 1 2 3 2 4 6 という結果を期待していた訳ですが、実際には 1 2 3 5 7 9 という結果になりました。 ということは、もしかしてメンバ変数ではなくともクラス内に現れるstatic変数はstaticなメンバ変数と同等ということなのでしょうか? 実際、上記ソースのforループ内にもう一つclass TAのインスタンスtbを追加してみると、 --------------------------------------- for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); TA tb; tb.func(i); tb.func(i); tb.func(i); } --------------------------------------- 1 2 3 4 5 6 8 10 12 14 16 18 となりました。 (まぁstaticではないメンバ変数に置き換えれば一応解決するのですが、個人的に何か凄く気持ち悪く感じて・・・)

  • Static Initializerについて

    JavaWorld Online - Javaの“常識”、“非常識” 第3回 http://www.javaworld.jp/technology_and_programming/-/27074-5.html 上記のURL内の記述によると 「static変数の初期化は、そのstatic変数を宣言する際、同時に行うことができます。しかし、宣言時ではなく、実行時に初期化したいというケースもあるでしょう。そのような場合に、この静的初期化子を使用します。」 とあり、宣言時の初期化とStatic Initializerを使用した場合でタイミングが異なると読み取れる記述があります。 が、意味がよく分かりませんでした。Date型を現在日付で初期化する簡単なプログラムで確認したのですが、同じタイミングで初期化されるように見えました。正確には変数が初期化された直後にStatic Initializerが動いてました。 そしてこの順番は(私のプログラムでは)インスタンス化する場合と、インスタンス化せずにstatic publicで定義しているクラス変数にアクセスする場合ともに結果は同じでした。 もしかしたらHPの記述が間違っているのかなーとも思いますがよく分かりません。 知りたいのは両者のタイミングの違いです。 Static Initializerについてご存知の方よろしくお願いします。 ※字数の関係から今回はソースを添付できませんでしたが、ご希望があれば質問の補足で添付します。

  • staticメソッドにするかどうかの判断

    staticメソッドの使いどころについて質問させてください。 まず、メソッドの内部で、そのメソッドが定義されているクラスのイ ンスタンス変数を使用している場合は、そのメソッドはインスタンス に依存するので、インスタンスメソッドにしかできないのはわかり ます。疑問なのは、「じゃあこのメソッド内でインスタンス変数を使 わないで引数で渡せるように作れば、インスタンスに依存しないの でstaticにしていいの?」(※)ということです。 さらにこうも思います。 なんとなくですが、※のようなことをしたらオブジェクト指向の意味 がない気がします。理由ははっきりわかりません。ほんとになんとなく です。(奇跡的にあたっていたとしても、理由を教えて下さいm(_ _)m) そして、さらに混乱するのが、ユーティリティの関数などでstaticメ ソッドになっているのを見ました。この場合はどうしてメソッドの引 数を指定するようにしていて、クラスのインスタンス変数を使うこと はしないのか。 以上、大変下手な文章ですが、混乱しているポイントが伝わったでし ょうか? よろしくお願いします。

  • Staticイニシャライズについて質問

    JAVA初心者です、宜しくお願いします。 Staticについて質問します。 ある本には、「static変数の初期化方法は、変数の初期化と同じステートメントで実行する方法と、JVMによってクラスがロードされるときに実行される特別なコードブロックを作成して変数を初期化する方法があります」とかかれていました。 ・ 「変数の初期化と同じステートメントで実行する方法」と「クラスがロードされ るときに初期化する方法」とは、どのように違うのでしょうか。   クラスがロードされる時とはどのような時なのでしょうか。 ・ 「変数の初期化と同じステートメントで実行する方法」については通常の方法な ので理解できるのですが、「クラスがロードされるときに初期化する方法」を行う と、どのようなメリットがあるのでしょうか。   何故このような方法があるのでしょうか。 以上、宜しくお願いします。

    • ベストアンサー
    • Java
  • static constメンバ変数(配列)の初期化について

    C++初心者です。 constメンバ変数の初期化について教えてください。 クラスの中に、static constメンバ変数(配列)を持ちたいのですが、 <コード1> class hoge { public : hoge(){}; virtual ~hoge(){}; static const int fuga[2] = {1, 2}; }; とすると、VC++ 2005では、 error C2059: 構文エラー : '{' error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます というエラーが発生します。 何がいけないのでしょうか? また、下の様にするとOKでした。 <コード2> class hoge { public : hoge(){}; virtual ~hoge(){}; static const int fuga[2]; }; const int hoge::fuga[2] = {1,2}; こうすればコンパイルが通る事は分かったのですが、なぜこんな面倒な事をしないといけないのかが分かりません。 コード1では何がいけないのでしょうか? 以上、よろしくお願いします。

専門家に質問してみよう