• ベストアンサー

static付き宣言の初期化

Lara-Portの回答

  • Lara-Port
  • ベストアンサー率36% (12/33)
回答No.1

C言語では、ANSIの仕様・宣言する位置に限らず、変数は初期値を入れない限り、不定値となります。(偶然、割り当てられた領域が0である場合は初期化されているように見えますが…) ですので、初期値が必要な場合は、main()や各関数の前半で、初期化する習慣をつけましょう。 今回の関数の場合、以下のようにされればいいのではないでしょうか。(static変数の使い方を理解してると仮定して書きます) <関数の呼び出しが1回目のみ初期値をもつとき> int func(void) { static int si = 0; static char *scp = NULL; static char sca[10] ={ NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL }; /* 何らかの処理 */ return 0; } <関数を呼び出すたび初期値をもつとき> int func(void) { static int si; static char *scp; static char sca[10]; /* 初期化 */ si = 0; scp = (char*)NULL; memset( sca, 0, sizeof(sca)); /* 何らかの処理 */ return 0; }

noname#2045
質問者

お礼

ありがとうございます。 誤っているということなので、特にコメントはございません。

関連するQ&A

  • static宣言について

    現在、c言語とDXライブラリを使ってゲームを製作しています。 http://okwave.jp/qa/q8270456.html 前回、このような質問をさせていただき、原因らしき箇所を突き止める所までいきました。 と言いますのも、配列の要素を指定する箇所(分かり辛かったらすいません。要素数ではありません)に、static宣言された変数を入れるとなぜかプログラムが強制終了されてしまうのです。 加えて、DXライブラリのGetColor関数にも返ってきた色をStatic宣言された変数に格納すると、何故か指定された色と違う色が出てしまうことが分かりました。 なんとか、その関数が終わる度に値を格納したかったので、色々試しました。 直接Static宣言されていない変数を間に噛ませてみたり、同じcpp内にわざわざ別の関数を用意して、そちらでStatic宣言し、値を返してみたり、と色々とやったのですが上手くいきませんでした。 ****************************************** int hairetu[20]; Static int z = 0; int x = z-1+1 hairetu[x] = zahyouX; (static宣言された変数zでhairetu[]の[]内を指定しようとするとダメ) (上記のように意味のない計算をさせてstatic宣言されていない変数を間にかませてもダメ) ****************************************** 結局の所、別のcppを用意して、ただ一つのStatic変数を+1していくだけの関数をくみ上げた所、上手くいったのですが・・・。何故このような事が起きるのでしょうか。 Static宣言された変数の決まりごと、もしくは、このような状態になってしまった原因など、見当がつきましたら教えていただけると有難いです。よろしくお願いします。

  • 関数原型宣言について

    関数原型宣言について 下記のプログラムのfunc関数は、関数原型宣言 <func(int a, long b, char *c);>が述されていないのにfunc関数の仮引数の型longは、関数原型宣言が与えられるといると本に書かれていたのですが、何故でしょうか教えて頂きたい。 ******************************************** #include <stdio.h> /*--- 三つの引数を受け取る関数 ---*/ void func(int a, long b, char *c) { int x; long y; /* … */ } int main(int argc, char *argv[]) { int a = 1; char s[] = "abc"; func(a + 3, 2, s); return (0); } *************************************************************

  • クラス内の関数内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変数の配列の初期値を空文字列にする一般的な方法

    いつもお世話になっております。 static変数の配列の初期値を空文字列(各要素が'\0')にしたいです。 static変数なので放って置いても各要素に'\0'が入りますが、 初期値として空文字列にしている事を明記したいです。 そこで以下の様な方法を考えてみました。 (1)初期値に何もせず、コメントを書いておく (2)初回起動フラグを持ち、フラグが立っていれば空文字列にする (3)初期値にnull文字をSTR_LENの数だけ書く (4)初期値の先頭のみnull文字にし、残りは省略する どの様な方法が一般的でしょうか? 上記以外にもあれば、教えていただければ幸いです。 また、以下は私が考えたそれぞれの方法のソースです。 -------------------------------------------------------------------------------- #include <stdio.h> #include <string.h> #define STR_LEN 16 #define FLAG_ON (1) #define FLAG_OFF (0) -------------------------------------------------------------------------------- /* 初期値に何もせず、コメントを書いておく */ -------------------------------------------------------------------------------- void clear_1(void) { static char hoge[STR_LEN]; /* 空文字列 */ } -------------------------------------------------------------------------------- /* 初回起動フラグを持ち、フラグが立っていれば空文字列にする */ -------------------------------------------------------------------------------- void clear_2(void) { static char hoge[STR_LEN]; static int first = FLAG_ON; if(first == FLAG_ON){ strncpy(hoge, "\0", STR_LEN); first = FLAG_OFF; } } -------------------------------------------------------------------------------- /* 初期値にnull文字をSTR_LENの数だけ書く */ -------------------------------------------------------------------------------- void clear_3(void) { static char hoge[] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'}; } -------------------------------------------------------------------------------- /* 初期値の先頭のみnull文字にし、残りは省略する */ -------------------------------------------------------------------------------- void clear_4(void) { static char str[STR_LEN] = {'\0', }; } --------------------------------------------------------------------------------

  • static宣言 について教えてください

    C言語の初心者です。内部的なstatic配列の理想的な応用例だと教科書に書いてありますが、static宣言しなくてコンパイルしても、普通に動きます。どうしてでしょうか。 char *month_name( int n ) { static char *name[] = { "Illegal month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; return ( n<1 || n>12 ) ? name[0] : name[n]; } ちなみに下のように書き換えると、static宣言しないとうまく動かなくなります。この二つの違いがわからないです。お願いします。 char *month_name2( int n ) { static char name[13][10] = { "NG", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th" }; return ( n<1 || n>12 ) ? name[0] : name[n]; }

  • static変数とマルチスレッド

    よろしくお願いします。 マルチスレッドとstatic変数の関係で悩んでいます。 マルチスレッドでグローバルstatic変数は __declspec(thread) static int kensu; ってしないと、マルチスレッド間で同じものになってしまうのはわかっているのですが ファンクション内の場合はどうだったのかわかりません。 ---------------------------- static int aa; multi_th() { func(); } func { static int bb; } ---------------------------- この場合、変数aaはマルチスレッド同士で同じものとなると思うのですが 変数bbはマルチスレッド同士で同じものになってしまうのでしょうか よろしくお願いします。

  • staticのスコープについて

    //main.c #include "myfunc.h" #include <stdio.h> static char hoge[10]; int main(void){ myfunc(hoge); printf("%c",*hoge); } ------------------ //myfunc.h void myfunc(char *hoge) { *hoge = 'a'; } 上記のようなプログラムの場合、 a と表示されると思いますが、この動作は保証されているのでしょうか? つまり、staticにて宣言したモジュール内の変数は、他モジュールにポインタを渡しても、内容は保証されるのかどうかと言う事なのですが。 よろしければ教えてください。

  • 初期化

    int Func_read(void) { char*prtn1; char*prtn2; char szdat1[81]; char szdat2[81]; int nrtn; prtn1=fgets(szdat1,81,Fp1); prtn2=fgets(szdat2,81,Fp2); if(prtn1==NULL||prtn2==NULL) return(9); nrtn=memcmp(szdat1,szdat2,81); if(nrtn!=0) return } というプログラムで領域のすべてを比較するため、領域を0で初期化しなけれればなりません。どこで初期化すればよいでしょう?

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

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

  • staticで初期化した変数(?)を使って初期化

    次の3つのプログラム、1番目はコンパイルエラーになりますが、下2つはエラーになりません。1番目のプログラムのエラーメッセージ:初期化子が定数ではありません。 処理系にかかわらずそうだとしたら、その理由はなんでしょうか。 ---------------------------------- int main(void) { static int a=5; static int b=a; return 0; } ---------------------------------- int main(void) { static int a=5; int b=a; return 0; } ---------------------------------- int main(void) { int a=5; int b=a; return 0; }