Version 5.04
文字ってなーに
「さて、今回は難敵、文字列ってものについて見ていきます」
『げ、難敵なの?』
「そ。ポインタが難しいって言われる理由は3つ。ひとつはメモリのイメー
ジの仕方」
『ふたつめは配列よね』
「で、みっつめはこの文字列の操作方法。でもこれを乗り越えれば」
『楽勝?』
「うーん」
『むー』
「……で、文字列の前に、まず文字から」
void A_Char()
{
char ch = 'A';
TRACE( "%c, %X\n", ch, ch );
// A, 41
}
『 char って1バイトサイズで、整数入れてるよね。でもなんで文字が入る
の?』
「 A が ' (アポストロフィ)で囲まれてるでしょ」
『あ、ホントだ、ダブルコーテーションじゃない』
「実は、文字って数字なんです」
『はい??』
「正確に言えば2進数のオンとオフ、ね」
『あ、コンピューター上のものは全部そうなんだもんね』
「文字もそう。もし普通に〈手書きの文字〉をコンピューターに取り込んだ
ら」
『全部CG?』
「そうなっちゃう。それじゃ大変だから、文字を数字で表すことにしたわけ」
『これ見ると、 A は16進で 0x41 ってこと?』
「そういうこと。コンピューターは、 A って文字を 0x41 って数字に変換
するわけ」
『変換って、どうやって?』
「変換用の表があるの。えっと、 MSDN 開いて【ASCII コード】ってページ
開いてみて」
『ほいっと』
【ASCII 文字コード】というページが開く。いくつもの表が並んでおり、
それぞれに記号や数字、文字が書かれている。
『う”、なんかよく分かんない』
「この変換表を【文字コード】って言います。右から2番目の列、上から2
番目を見てみて」
『 A B C ってなってるね。あ、その左の数字が 41 42 43 ってなってる!
もしかしてこれが A が 0x41 ってこと?』
「そういうこと。ちなみに Dec は decimal 、10進数って意味。 Hex は
hexadecimal で」
『16進数って意味でしょ』
「そういうこと。で」
『ああっ!!』
「な、なに?」
『もしかして、 TRACE() に使ってた %d って decimal の d なんじゃない?
%X は hexadecimal の X とか』
「うん、たぶんそうだと思うよ」
『はー、なんかここに行き着くのにすごーく時間がかかったよーな』
「確かに……。さて、 A が 0x41 って数字ってことは分かったでしょ。逆
に char 型変数に入ったこの 0x41 って数字を文字に変換するにも」
『さっきの文字コード表ってのを使うんだ』
「そういうこと。 0x41 って数字を〈Aだ!〉って認識して、文字として表
示してくれるわけ。それが」
『 TRACE() で %c 渡してるとこよね。こう指定したから A って表示されて、
%X って指定したら、数字の 0x41 って表示してくれる』
「そう。前に言ったかもしんないけど、結局、コンピューターのデータって
いうのはメモリ上のオンオフだけ」
『それをどうみなすか、よね。 int の負の整数とかバイトオーダーとかで
散々聞かされてきたもんねー』
「うん、その辺は大事だからね。ちなみに」
『 %c の c はやっぱ char よね』
「そ、そう……あ、そう、で、 char は character の略ね」
『あれ、 char ってただの1バイトサイズの型だと思ってたんだけど、もし
かして文字入れる専用?』
「1バイトサイズだから、普通の整数はまず入らないからねぇ」
『そういえばそうね。なんか、ずっと整数値入れるもんだと思ってたのに、
文字を入るのだったのねー』
「別に int に入れても問題ないけど」
『あ、そういえば』
「それに、なんで1バイトサイズで十分なんだと思う?」
『あ、そういえば。文字コード見ると、1バイトサイズまでしか文字がない
ね』
「 A から Z と a から z 、それに記号あわせても255は超えないからね。
だから char で十分」
『あれ、それって unsigned じゃない?』
「ぎく! そう、文字コードって、数字っていうよりも16進数のデータと
しての面の方が強いから、 unsigned char の方がいいかもね」
『うん、あたしもそう思う』
「でも面倒だから unsigned 付けられないこと多い……」
『げ、なにそれ』
「この辺にも色々問題があるんだわ。ま、それは今回は置いておくことにし
ましょう」
『もひとつ質問。漢字とかは? 255文字に入らないでしょ』
「ふっふっふー、それがまた大変なんだ」
『げげ』
「ま、日本語の話はまたこんど。とりあえず今は、文字は数字で、その変換
は文字コードでできて、文字ひとつの数字は char 型の変数に入る」
『うんうん、その辺ならなんとか分かるかも』
「じゃ、ずーっと昔を振り返ってみましょう」
『ずっと昔? 平安京とか?』
「なぜに平安時代。 Ver 1.0 ( No.003 )を見て」
『うっわすっげー昔!!』
「どう、読んでみて」
『うっわ、プログラミングができるって知ってうれしがってる、わけー!!』
「って、わざとおじさんっぽく言わないよーに」
『はー、そういえばこのとき、テキストファイルをバイナリーモードって
ゆーので見てるんだね。なんかメモリ見てるのと似てる』
「ほとんど同じだよ。メモリもディスクも同じオンオフの世界だもの」
『あ、そうか。で……』
数字: 61 62 63 64 65 66 67 68 69 を、
文字: a b c d e f g h i
『うわ、これって ASCII 文字コードそのままじゃん!!』
「でしょ。つまりファイルの中も同じ、数字が入ってて、それを ASCII
コードに変換して表示してるってだけ」
『これもみなしねー。あ、こんなかで〈数字と文字〉みたいなのやって
る。そいや ASCII 文字コードで見ると、 1 は 0x31 なんだね』
「さっきの関数で 'A' を '1' にすれば分かるよ」
『なるほど。…… 1 は整数値だから char に入る、 '1' == 0x31 も整数値
だから char に入る……』
「ってことは、 1 って数字を '1' に変換するには?」
『 0x30 を足す!』
「そういうこと。プログラム書いてみ?」
void char2character()
{
char ch = 1;
ch += 0x30;
TRACE( "%c, %X\n", ch, ch );
// 1, 31
}
『まず char の変数作って 1 入れて、それに 0x30 を足すと '1' になる、
これを %c で表示すれば 1 になる!! それに……』
char ch = 2;
『ってすればちゃんと 2 が表示される!! すごい! すごいよ水希ちゃ
ん!!』
「そう、整数を文字に変換する基本的な部分は、こういうこと。これで、昨
日の (LPCTSTR) ってキャストが無茶苦茶だってこと、少し分かるでしょ?」
『そっか、文字の時と数字の時、全然中身が違うんだもんね。そーゆー変換
をしなきゃいけないってことなんだ』
「そういうこと」
『でもこーやって変換すればいいんでしょ? 楽勝っぽいけど〜』
「 ch には1文字しか入らないんだから、 100 とかは変換できないでしょ」
『う”』
「そこで出てくるのが文字列、ってもの」
void StringArrayAddress()
{
char chAry[] = "ABC";
TRACE( "%X\n", chAry ); // ここにブレークポイント。
}
『えっと、新しいのって配列のとこだけだよね』
「そう、ここ」
char chAry[] = "ABC";
『配列作ってるんだよね。でも、何個かっていうの指定してないよ?』
「指定してない場合には、必要な分だけ確保されるから。さっき見たように、
char 変数一個につき1文字、だと、 ABC なら変数何個必要?」
『3つ!』
「そう。で、答は4つね」
『……??』
「まあこれは置いといて、実はこれは文字列だけの特別な方法」
『どゆこと?』
「普通の int の配列とかじゃ、こういうふうに配列に値を入れられないっ
てこと」
『おー』
「こうすると、配列の要素ひとつひとつに文字を入れてくれて、しかも自動
的に必要なサイズになってくれるんです。じゃ」
『ブレークポイントセットしてメモリを見る!』
41 42 43 00 8C F5 64 00 E2 19 40 00 2C F8 64 00 C0 01 52 00 ABC....
『あ、 41 42 43 、なんかバイナリーエディタで見たときと同じ感じ』
「それぞれのマスはどの変数を指してる?」
『えっと、 char は1バイトだから、 chAry[0], chAry[1], chAry[2] だよ
ね。あ、なるほど、 char 1個につき1文字ってこーゆーことね』
「そう。実際に見てみると……」
void CharsArray()
{
char chAry[] = "ABC";
TRACE( "%c, %c, %c\n", chAry[0], chAry[1], chAry[2] );
// A, B, C
}
『お”お”、ちゃんと1要素1文字になってる!』
「でしょう、こうやって確認しないとね。ちなみにさっきのメモリので、一
番右の ABC っていうのは、メモリ上のデータを無理矢理 ASCII 文字コード
に変換したもの」
『なんか変な日本語が表示されたりしてる……』
「まあ要するに重要なことは、〈文字列〉でも、原則的には char ひとつに
文字ひとつ、ってこと」
『だから char の配列にするのね。ってことは、 100 を文字列に変換する
ときには、 100 のひとけたずつを char 配列のひとつひとつに変換してい
かなきゃいけないってことなんだ。なんかめんど……』
「その辺はちょっと考えれば簡単に処理できるけど、その前に文字列につい
て触れておきます」
『なんで答は4つなのかとか教えてくれる?』
「もちろん! というわけで次回に続く!」
/*
Preview Next Story!
*/
『あ! バイナリーってどーゆー意味?』
「 binary は2進数って意味」
『でも表示は16進数じゃん』
「2進数を4つまとめて表示したのが16進数だからね」
『というわけで次回』
< Version 5.05 配列と文字列 >
「につづく!」
『〈素のデータ〉っていうのも間違いじゃないかも』
「僕は嘘は言わない!」
『なんか騙されてるよーな気が……』