39095


C言語入門 (ASCII SOFTWARE SCIENCE Language) という本の以下の部分についての質問です。

> 自動変数の初期化は、いわゆる「実行時」の現象であり、静的変数の初期化は、「コンパイル時」の現象なのです。
> 言い換えれば、コンパイラは静的変数のために記憶領域を割り当て、そこに変数の初期値を格納します。したがって、プログラムが実際に実行される時、静的変数の値は既に存在しています。
>
> (略)
>
> 静的変数は、それが本当に必要だと思われる場合のみに使用する事を推奨します。  
>  なぜなら静的変数は、それが実際に必要でないときも、常に値をメモリ中に保存しているからです。

これは、プログラムの実行前(a.exeをクリックする前)から  
メモリ上に静的変数のために記憶領域は割り当てられているという事でしょうか？

普通に考えると「そんな訳無いだろ」とは思っているのですが、  
「プログラムの実行時(a.exeをクリックした時)に1回だけメモリ上に静的変数のための記憶領域を確保する」と解釈すると、  
わざわざ「コンパイル時の現象」と言っている意味が分かりません。


CC BY-SA 3.0
2017-10-28T04:43:21.630
39093
2017-10-28T10:20:27.130
2020-06-17T08:14:45.997
-1
25791
question
c
静的変数の記憶領域の割り当てについて


当該書籍は持ち合わせていないので前後の文脈はわかりませんが…

> これは、プログラムの実行前(a.exeをクリックする前)からメモリ上に静的変数のために記憶領域は割り当てられているという事でしょうか？

そういうわけではありません。

  1. コンパイル時に静的変数に格納される内容・値は決定され、
  2. プログラム開始時に静的変数の領域は用意され、
  3. プログラム開始時に1.で決定された値で初期化される

という意味です。例えば

[code]

    int rnd = rand();
    
[/code]

とすると実行時に乱数を生成し、変数`rnd`に値を格納します。つまり、変数の領域もそこに格納される値も実行時に決定されることを意味します。しかしこれを静的変数として

[code]

    static int rnd = rand();
    
[/code]

とすることはできません。これは変数`rnd`の値がコンパイル時に確定できないためです。


CC BY-SA 3.0
2017-10-28T05:26:09.677
39095
2017-10-28T05:26:09.677
4236
39093
answer


> 常に値をメモリ中に保存しているからです。

の文章に「当該プログラムの実行中は」の一言を補ってください。静的変数を持つプログラムを作っただけ＝実行していない状況で、あなたのコンピュータのメモリが無駄になることはありません。

「コンパイル時の現象」についてはすでに説明がある通り、静的変数の初期値として採用できるのはコンパイル時に値が確定できる式だけ、という意味です。（リンク時に値が確定できる式も初期値として採用できる場合があります）

[code]

    /* 関数の外にある大域変数とします */
    int foo=2+3*4; /* 14 になります */
    int* bar=&foo; /* 大域変数のアドレスは事実上リンク時に決まります */
    
[/code]


CC BY-SA 3.0
2017-10-28T10:20:27.130
39102
2017-10-28T10:20:27.130
8589
39093
answer