アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語において
int a = 1; // 動的グローバル変数
static int b = 2; //静的グローバル変数

funcA(){
int c = 3; // 動的ローカル変数
static int d = 4; //静的グローバル変数



}
上記のように各種変数を初期化したとします。
"c"のような動的ローカル変数であれば、funcA()が呼ばれたときに毎回初期化されますよね?

では
・"d"のような静的ローカル変数は、初めてfuncA()が呼ばれたときに初期化されるのですか?
・"a","b"のyほうなグローバル変数は、どのタイミングで初期化されるのですか?

以上2点について伺いたいと思います。

ちなみに、組み込み機器むけのソフトウェアを想定しています。

A 回答 (15件中1~10件)

インクリメント表示して二度呼ぶとすぐに結果出ますよね。

この回答への補足

ご回答ありがとうございます。

試し方がよくわからないのですが
もう少し具体的に教えていただけますか?

補足日時:2008/05/18 01:49
    • good
    • 0

>・"d"のような静的ローカル変数は、初めてfuncA()が呼ばれたときに初期化されるのですか?



そう思って良いでしょう。実際のタイミングはmain()実行の直前と思いますが、同じ事です。

>・"a","b"のyほうなグローバル変数は、どのタイミングで初期化されるのですか?

これもmain()実行の直前です。
ちなみに、グローバル変数に、静的・動的の区別はなく強いて言えばすべて静的です。そうするとstaticキーワードの意味が余るので、名前の有効活用の意味で関数やグローバル変数に付けられたstaticキーワードは別の意味を持ちます。「グローバルだけど他のファイルで定義された関数からはアクセスできない」という意味です。ローカル変数の動的・静的とは関係ありませんので、本来は別のキーワードを使えば混乱がなかったと思いますが、予約語を増やしたくなかったんでしょう。

この回答への補足

すいません。
言葉を間違えていました。

staticは静的変数
記載なし(記載するならauto)が動的ではなく自動変数でした。

補足日時:2008/05/18 00:54
    • good
    • 0

>int a = 1; // 動的グローバル変数


>static int b = 2; //静的グローバル変数
関数外で宣言された変数はstaticと解釈されますので、
上記の記述に差はありません。
ちなみに、動的グローバル変数という言葉は聞いた事がありません。


staticと解釈された関数や変数はプログラムが実行される際に、
メモリにその領域が確保されます。

一方、dynamicと解釈された関数や変数は、
呼ばれたときにメモリに領域が確保されます。

ご提示いただいた変数でいうと、
a、b、dはプログラムが開始されたときに領域確保+初期化され、
cは関数開始時に領域確保+初期化されるはずです。

No.1の方がおっしゃるように、一度試されるとよいでしょう。
    • good
    • 0

> >int a = 1; // 動的グローバル変数


> >static int b = 2; //静的グローバル変数
> 関数外で宣言された変数はstaticと解釈されますので、
> 上記の記述に差はありません。

そんなことはないです。明確な違いがあります。
下記のサンプルコードで試してみてください。

// temp.c
#include <stdio.h>

int a = 1;
static int b = 2;

void func(void);

int main(void)
{
func();
return 0;
}

// temp-2.c
#include <stdio.h>

extern int a;
extern int b;

void func(void)
{
printf("a=%d\n", a);
printf("b=%d\n", b);
}

func()において、どこか別のファイルで定義した変数a, bの内容を
出力しようとしています。
変数aは正しく認識できますが、変数bはtemp.cの外からは見えません。
リンク時に「外部シンボル未解決」というエラーが出ます。
    • good
    • 0

> dはプログラムが開始されたときに領域確保+初期化され、



これも正しくないですね。
dはあくまでも関数内のローカル変数ですから、
当該関数の実行時に領域確保と初期化を行ないます。
仮に、当該プログラムが一度も当該関数を実行しないとすると、
dのための領域は当該プログラムの実行中確保されません。
staticが付いているから、一度領域を確保すると、
当該プログラムの実行中ずっとその内容を保持している、というだけです。
    • good
    • 0

組み込み向けですよね。


どのコンパイラか分からないので一般論ですが、通常はデータセクションに最初から埋め込まれています。
データセクションはROM領域に乗るのが普通なので、何らかの方法でRAMにコピーして使います。大抵はブートコードでコピーするはずです。

どのタイミングといわれれば、コンパイル時かブート時ということでいいんじゃないでしょうか。
    • good
    • 0

★アドバイス


 組み込み系は詳しくありませんので一般論で回答しておきます。注意。
・次のリンクの
 『セクションとか.textとか』
 『初期化してない変数とか.bssセクションとか 』
 を読んでみて下さい。
 http://www.ertl.jp/~takayuki/readings/info/→『「infoを読め」と言われたら...』
 さらに詳しく知りたい場合は『BSS セクション』で検索してみましょう。
>"c"のような動的ローカル変数であれば、funcA()が呼ばれたときに毎回初期化されますよね?
 ↑
 自動変数だね。
 毎回初期化されます。
>"d"のような静的ローカル変数は、初めてfuncA()が呼ばれたときに初期化されるのですか?
 ↑
 これは『a』『b』と同じくスタートアップ・ルーチンで初期化されます。
 スタートアップ・ルーチンはmain()関数が呼ばれる前の処理です。
 プログラムが起動した最初の1回しか初期化されません。
>"a","b"のyほうなグローバル変数は、どのタイミングで初期化されるのですか?
 ↑
 これも『d』と同様にスタートアップ・ルーチンで初期化されます。
・最後にもう一つ次のリンクを読んでみて下さい。
 http://www.ertl.jp/~takayuki/readings/c/no10.html→『初めてのC言語 - 第10回 三度目のスタートアップ』
    • good
    • 0
この回答へのお礼

大変参考になるサイトご提示いただき
ありがとうございました。

お礼日時:2008/05/25 18:59

a, b, dはいずれも静的記憶域期間を持ちます。

初期化は通常スタートアップで行います。
ちなみに、aは外部結合、bは内部結合、dは無結合になります。

cは自動記憶域期間を持ちますので、funcAが呼び出され、その宣言部分に実行パスが差し掛かるたびに初期化されます。

これに関しては、組込みであろうがなかろうが関係ありません。ただし、main関数云々の話はフリースタンディング環境では通用しません。

この回答への補足

>みなさま
丁寧なご回答ありがとうございます。
"c"の自動ローカル変数に関しては、関数呼び出し時に初期化でOKのようですが
"a","b","d"に関しては意見が分かれるようですね。
まとめると
1."a","b","d"ともコンパイル時にメモリに領域が確保されると同時に初期化される。
2."a","b","d"ともスタートアップルーチン時にメモリに領域が確保されると同時に初期化される。
3."a","b"はスタートアップルーチン時、"d"は該当関数が呼ばれた時にメモリに領域が確保されると同時に初期化される。

の3種類の意見に分類できそうですが、これは環境によって初期化の方法が違うのでしょうか?

私の場合は、Winマシンでcygwinというコンパイラでコンパイルし
組み込み機器のROMにファームを焼き
機器の電源ONと同時にブートローダによってファームをROMからRAMに移す
といった処理をしています。
ちなみに機器のOSはLinuxです。

補足日時:2008/05/18 01:28
    • good
    • 0

★アドバイス


>1."a","b","d"ともコンパイル時にメモリに領域が確保されると同時に初期化される。
 コンパイル時ではありません。
 実行されたときに初期化されます。
>2."a","b","d"ともスタートアップルーチン時にメモリに領域が確保されると同時に初期化される。
 これです。
 BSSセクションをすべてゼロで初期化。
 その後に指定された『値』1とか2などで初期化。
 この順です。
>3."a","b"はスタートアップルーチン時、"d"は該当関数が呼ばれた時にメモリに領域が確保されると同時に初期化される。
 これは間違いです。
    • good
    • 0

a, b, dのメモリ領域はコンパイル時に割付けられます。

より厳密に言えば、具体的なアドレスが決定するのはリンク時です。

静的記憶域期間を持つ初期値付きオブジェクトは、一般的には、.dataセクションに配置され、スタートアップでROM→RAMに転送されます。ただし、今回の場合は、.textセクションのプログラムと一緒にブート時に転送されることになると思います。
ゼロクリアされるのは.bssセクション(つまり初期値無しオブジェクト)だけです。

dに関しての誤解は、C++における定数式以外の初期化子との混同ではないかと思います。例えば、

void func()
{
 double y = std::sqrt(3.0);
 ...
}

のyは、funcが呼び出され、最初にyの宣言位置に実行パスが差し掛かったときに初期化されます。それ以前はゼロクリアされることになります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!