ページ 1 / 1
終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 11:13
by なんだうを
終端文字 ¥0 の意味がよくわかりません・・・・。
苦しんで覚えるC言語というサイトで勉強しているのですが、
#include <stdio.h>
int main(void)
{
char str[6] = {'M','A','R','I','O','¥0'};
printf("%s¥n",str);
return 0;
}
実行結果:MARIO
もしも文字列にEOSがなかった場合は、配列の先まで文字列として扱われるので、
偶然にどこかで0(EOS)が見つかるまでは、
延々と文字列が表示され続けることになり、とても困ります。
↑これの意味がよくわからないです。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 11:31
by softya(ソフト屋)
ここのフォーラムルールに書かれているのですが、codeタグを使ってくださいね。
http://dixq.net/board/board.html#k10
この機会にフォーラムルール全体を読んでくださいね。
終端文字 ¥0 はC言語の基本的な文字列を扱う時のルールですね。
C言語の文字列は文字配列を使っているのですが、C言語は配列の大きさを実行時に把握する機能を持っていません。
それはすなわち文字列の長さを知るすべがないと言うことになります。
その代わりとして、終端文字 ¥0 を見つけたら文字列の終わりと見なしましょう。
と言うお約束でC言語は文字列を扱います。
なので、終端文字 ¥0 を入れ忘れるとどこまでも文字列が続いているとして処理しようとします。
とりあえず、こうやったら実感できませんか?
コード:
#include <stdio.h>
int main( void )
{
char str[5] = {'M', 'A', 'R', 'I', 'O'};
char str2[6] = {'W', 'A', 'R', 'I', 'O','¥0'};
printf( "%s¥n", str );
return 0;
}
どうですか納得する結果は得られましたか?
疑問に思ったらプログラムで実際に試して見ると分かることもありますよ。それがプログラミングの勉強方法です。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 11:35
by box
なんだうを さんが書きました:終端文字 ¥0 の意味がよくわかりません・・・・。
C言語において、文字列のおしまいを示すために、'\0'(16進数では0x00)を
使うことになっています。
もし、終端文字がなくて、
なんだうを さんが書きました:
コード:
char str[] = {'M','A','R','I','O'};
と定義した場合に
と書くと、配列str[]自身に終端文字'\0'が存在しないため、
printf()は、メモリー中のどこか(おそらくは配列str[]の続き)に存在するであろう
'\0'を延々と探しに行きます。探しに行った結果として、偶然にもstr[]のすぐ後ろに
'\0'が存在した場合は
なんだうを さんが書きました:
実行結果:MARIO
これと同じ結果に偶然なります。しかし、str[]のすぐ後ろに'\0'が存在しなかった場合
(一般にはこちらだと思ってくださってかまいません)は、'\0'を延々と探しに行った結果、
なんだうを さんが書きました:
実行結果:MARIO
このようにはならずに、"MARIO"の後ろに意味不明な文字列を出力することになるでしょう。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:01
by なんだうを
すみませんでした。
コード:
#include <stdio.h>
int main( void )
{
char str[5] = {'M', 'A', 'R', 'I', 'O'};
char str2[6] = {'M', 'A', 'R', 'I', 'O','\0'};
printf( "%s\n", str);
printf( "%s\n", str2);
return 0;
↑で実行したら結果が
MARIO
MARIO
となったので、どっちでも変わらないような気がしてました。
これは偶然なったってことでしょうか?
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:13
by box
なんだうを さんが書きました:
これは偶然なったってことでしょうか?
そうです。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:13
by softya(ソフト屋)
失礼しました。狙った通りになりませんね。つまりコンパイラ依存の方法でした。
この状況でも出来る方法は・・・。
ちと考えてみます。 ところでVC++ですよね?
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:20
by softya(ソフト屋)
VC++限定ですが、これでおかしな事になるはずです。
コード:
#include <stdio.h>
int main( void )
{
char str[6] = {'M', 'A', 'R', 'I', 'O','\0'};
char str2[8] = {'W', 'A', 'R', 'I', 'O', 'O', 'O', 'O'};
printf( "%p,%p\n", str, str2 ); //文字列ポインタ表示
printf( "%s\n", str2 ); //WARIOOOOを表示したはずが?
return 0;
}
かならずコピペして実験してみてください。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:46
by なんだうを
すみません・・・開発環境とか書いてませんでしたね・・・。
テンプレをみてませんでした。以後気をつけます。
[2] 環境 はコンパイラはBorand C++です。
[3] その他
どの程度C言語を理解しているかですが、もともとプログラミングなどやったこともなく、
完璧に初学で苦しんで覚えるC言語というサイトをみながら必死こいて勉強して5日目くらいの理解しかありません・・・。
載せてもらったコードをコピペして実行してみました。実行結果は
0018FF4C,0018FF44
WARIOOOOMARIO
このように表示されました。この結果から自分なりに考えて、
これは、printf関数が配列strをみて’¥0’を探したが見つからずに、次のアドレスであるstr2まで行ってしまい、
そこで'¥0'を見つけて、そこまでを文字列と認識してそこまで表示したということであっているでしょうか?
ほんとにまだプログラミングというものに触れたばかりで、至らぬことがおおくてすみません。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 12:54
by softya(ソフト屋)
なんだうを さんが書きました:このように表示されました。この結果から自分なりに考えて、
これは、printf関数が配列strをみて’¥0’を探したが見つからずに、次のアドレスであるstr2まで行ってしまい、
そこで'¥0'を見つけて、そこまでを文字列と認識してそこまで表示したということであっているでしょうか?
はい。大体合っています。
一点間違えているのはstr2からスタートしているって事ですね。printf( "%s\n", str2 );
str2 str の順でメモリに格納されています。Borand C++も偶然VC++と同じ順番だったようです(コンパイラ依存)。
それとprintf関数が認識するのはstr2の開始アドレス(ポインタ)だけであって終端は終端文字 ¥0が出てくるまでって事だけです。
str2→strと2つの配列を跨ったことなど微塵も認識していません。
もう一つ秘密があって、WARIOではなくWARIOOOOにしているのはコンパイラの環境依存を逃れるための工夫なんですが難しいのでもう少し勉強してから考えてみてください。
ポインタあたりをちゃんとやってからじゃないと理解できないと思います。
>ほんとにまだプログラミングというものに触れたばかりで、至らぬことがおおくてすみません。
【追記】
十分進んでいると思いますよ。
それに良い所に疑問を持ちましたね。
そういう疑問を持ち続ければプログラミングの習得にプラスになります。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 13:05
by なんだうを
softya(ソフト屋) さんが書きました:
一点間違えているのはstr2からスタートしているって事ですね。printf( "%s\n", str2 );
ですよね。これは書き間違えました。
環境依存を逃れるための工夫などはまだぜんぜん意味もわかりませんし、今ポインタでちんぷんかんぷんになりかけてる感じですが、なんとかプログラミングを取得して行きたいです!疑問に答えてくれてありがとうございました!
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 14:49
by 赤鬼
解決押し忘れてます?
コード:
int main(){
char str[2][6]={
"MARIO",
"LUIGI"
};
printf("%s\n",str);
str[0][5]='&';
printf("%s\n",str);
getchar();
return 0;
}
環境依存無しのコードだと思います。
両方供同一の先頭ポインタを渡していますが、結果は違います。
試して見て下さい。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月15日(月) 20:17
by なんだうを
すみません解決押し忘れてました。
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月16日(火) 14:14
by フリオ
コード:
int main(){
char str[2][6]={
"MARIO",
"LUIGI"
};
printf("%s\n",str);
str[0][5]='&';
printf("%s\n",str);
getchar();
return 0;
}
>環境依存無しのコードだと思います。
この動作は、未定義じゃないのでしょうか?
Re: 終端文字 ¥0 とは・・・
Posted: 2012年10月16日(火) 17:42
by box
フリオ さんが書きました:
この動作は、未定義じゃないのでしょうか?
なぜ未定義と思われましたか?