C言語関係掲示板

過去ログ

No.151.配列の初期化について


No.977

配列の初期化?
投稿者---akira(2002/01/29 14:09:58)


こんにちは。

配列の初期化(初期化になるのかな?)に関してです。
char strbuf[2];
char *strcp;
このstrbufに
strcp=strncpy(&strbuf[0],data,1);
等としてstrcpをこの後の処理で使うと動作がおかしかったので、
char strbuf[2]={0}; や
static char strbuf[2]; /* 今回 static にしたくは無いのでこっちは使えないのですが… */
として初期化?した後に使用すると正常に動作する様になりました。
質問1:これは妥当な修正になるのでしょうか? 
質問2:また、これが char strbuf[1024] の様な時も
char strbuf[1024]={0};
    で良いのでしょうか? 

ちなみに、同一のコード(char strbuf[2];のまま)を他のソースファイルに記述すると動いている時もありました。
こういう現象の原因、見当つきますでしょうか?(不定だから?かな?)
最後に:
配列を宣言する時には常に={0} としておいた方がbetterなのでしょうか?

色々と一気に質問してしまいましたが、どこか一つでもヒント頂けるとありがたいです。



No.978

Re:配列の初期化?
投稿者---B.Smith(2002/01/29 16:04:39)


こんにちは。

関数strncpyは次のように定義されていますよね?
    char *strncpy(char *str1,const char *str2,size_t count);

この関数は、countがstr2よりも大きい(長い)場合のみ、不足分を補うように、str1のコピー末尾部分にヌルを補充します。
今回はcountに1が指定されていますので、dataが0文字でない限り、ヌルは付加されません。戻り値にはstr1が返されますので、ヌルの付いていない文字列を処理することになります。

そのため、
>質問1:これは妥当な修正になるのでしょうか?
>質問2:また、これが char strbuf[1024] の様な時も
>char strbuf[1024]={0};
>    で良いのでしょうか? 

配列をヌルで初期化することになるので、プログラムとして正しいと思います。
ただし、本当に1文字しかコピーしないのであれば、
    strbuf[0] = *data;    strbuf[1] = 0;
    strcp = strbuf;

この方が効率は良くなります。
また、配列の初期化に関して、staticにしたくない、ということですが、文字列が可変長でない限り、本来ならばstaticにすることをお勧めするところです。ヌルで初期化する処理を省くことができるからです。auto変数として初期化した場合、これが関数内であると、関数が呼び出される度に初期化を実行してしまいます。

>最後に:
>配列を宣言する時には常に={0} としておいた方がbetterなのでしょうか?

処理がまったく問題ない、ということが分かっている場合には良いと思います。ただし、プログラム上の問題点を発見できなくなってしまうので、多用することはお勧めできません。また、上記の初期化の問題もあることから、効率性の面でもお勧めできません(staticならばOKです)。


No.984

Re:配列の初期化?
投稿者---akira(2002/01/29 19:30:48)


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

    char *strncpy(char *str1,const char *str2,size_t count);

>この関数は、countがstr2よりも大きい(長い)場合のみ、不足分を補うように、str1のコピー末尾部分にヌルを補充します。
>今回はcountに1が指定されていますので、dataが0文字でない限り、ヌルは付加されません。戻り値にはstr1が返されますので、ヌルの付いていない文字列を処理することになります。

そうなんですか。str1 にはヌル付きで帰ってきてくれるものとばかり思っていました。

>ただし、本当に1文字しかコピーしないのであれば、
>
    strbuf[0] = *data;    strbuf[1] = 0;
    strcp = strbuf;

>この方が効率は良くなります。
>また、配列の初期化に関して、staticにしたくない、ということですが、文字列が可変長でない限り、本来ならばstaticにすることをお勧めするところです。ヌルで初期化する処理を省くことができるからです。auto変数として初期化した場合、これが関数内であると、関数が呼び出される度に初期化を実行してしまいます。

この関数、何度も呼ばれて文字列 data は長さが変わって入ってくる可能性があります。ですんで、static にしちゃうと長い文字列の後に短いのが入ってきたらゴミが残ったまま処理されちゃうのでは?と思い、static はやめました。
上記で仰っている文字列が可変長とはこの解釈で合っていますよね?(違ったらご指摘下さい)
効率良いとのことなので、上記コードで試してみたいと思います。

>>最後に:
>>配列を宣言する時には常に={0} としておいた方がbetterなのでしょうか?
>処理がまったく問題ない、ということが分かっている場合には良いと思います。ただし、プログラム上の問題点を発見できなくなってしまうので、多用することはお勧めできません。また、上記の初期化の問題もあることから、効率性の面でもお勧めできません(staticならばOKです)。

やっぱり、一概には言えないですよね。
勉強になります。本当にありがとうございました。



戻る


「初心者のためのポイント学習C言語」 Last modified:2002.03.16
Copyright(c) 2000-2002 TOMOJI All Rights Reserved