ページ 11

printf関数の挙動について

Posted: 2014年3月03日(月) 18:44
by たかお
こんばんは。
C言語においての文字や文字列の扱いを勉強しようと考え、色々試していたところ不可解な現象が起きました。

コード:

void main(){

char b[] = "1abc";
char d[4];
d[0] = '1';
d[1] = 'a';
d[2] = 'b';
d[3] = 'c';

printf("%s\n",b);
printf("%s\n",d);

return 0;
}
このように記述したところ、実行結果が以下のようになりました。

1abc
1abc1abc

配列dに格納されている文字を表示する処理を一度しか行なっていないにも関わらず、実行結果では2回分表示されています。
一体なぜこのようなことになるのでしょうか。ご教授お願いします。

Re: printf関数の挙動について

Posted: 2014年3月03日(月) 18:49
by みけCAT
配列dのデータの最後にNIL文字が格納されておらず、たまたまdの領域とbの領域が連続していたため、
dのデータに続けてbのデータが表示されたと考えられます。
次のプログラムを同じ環境で実行してみてください。

コード:

void main(){
 
char b[] = "1abc";
char d[4];
d[0] = '1';
d[1] = 'a';
d[2] = 'b';
d[3] = 'c';
 
printf("%p %s\n",b,b);
printf("%p %s\n",d,d);
 
return 0;
}

Re: printf関数の挙動について

Posted: 2014年3月03日(月) 18:52
by box
printf関数の挙動が不審なわけではありません。

"1abc"
という、いわゆる文字列は、
'1'
'a'
'b'
'c'
'\0'
という5バイトの領域からなります。4バイトではなく。
いわゆる文字列を正しく扱うには、
きちんと'\0'で終端させることが必要です。

Re: printf関数の挙動について

Posted: 2014年3月03日(月) 19:05
by たかお
そういえば文字列配列の最後尾にはNULLが入るんでしたね。自動的に挿入されるのですっかり忘れていました。
文字列の配列を表示する際はNULLが見つかるまで連続したアドレスを参照するようになってるんですね。

みけCATさん、boxさん回答ありがとうございました!

Re: printf関数の挙動について

Posted: 2014年3月03日(月) 20:01
by box
NULL

'\0'
とは別物であることに留意してください。

Re: printf関数の挙動について

Posted: 2014年3月03日(月) 22:33
by たかお。
box さんが書きました:NULL

'\0'
とは別物であることに留意してください。
一緒くたにしてました。覚えておきます。ご指摘ありがとうございました。