文字列を扱う前に NULL を紹介しておきます。「文字列の終わりには NULL をつける。」の文章の意味と理由が分かる方は、この章はとばしていただいて結構です。
さて、前章のサンプルコードで computeSum 関数に計算するデータの個数も引数として渡しました。それは、computeSum 関数ないでは、計算するデータの個数、即ち、main 関数内で data[] の配列の数をいくつ定義したか分からないからです。#define などで、定義側と計算側で個数をあわすと言う手がありますが、それでは、汎用性がありません。一定の個数の合計しか計算できないわけですから。関数を作っていく上で、気をつけ無ければならないことの一つは、汎用性を持たせるという事です。例外を作らないとでも言えます。つまり、ある処理を実現する関数があったとして、Aのケースはこちらの関数を、それ以外はそちらの関数を使って下さい・・・、何てのは駄目です。最大限、場合分けは関数内で吸収します。よって、先の computeSum 関数内で計算するデータの数を一定にしてしまうのは問題です。よって、引数として計算するデータの個数を渡しています。これにより、将来的に同じような処理をしたい場合、computeSum 関数をコピーするなり、ライブラリにするなりすれば、再利用できるのでコーディングの手間が省けます。今回の computeSum 関数は簡単なので、すぐに作ることが出来ますが、複雑な関数ならばなおさらです。
だらだらと脱線しましたが、汎用性を持たせるために計算するデータの個数を引数として渡したけれど、そのためにわざわざ引数が一つ増えるのは面倒くさい。ましてや、文字列は確実的にの配列としてデータを扱うのだから・・・。と言うのも実際の所です。文字列は char 型の配列を用いて表します。この char 型の配列の数は扱いたい文字列が入ればいくらでもOKです。そして、使っている部分と、使っていない部分、即ち、配列内で扱っている文字列の終わりを表す記号のような物をその配列内に入れれば、文字列を扱う関数に配列の個数を渡さなくても済むというのが、文字列の場合の配列の考え方です。その記号か NULL です。ある関数が、文字列の先頭のポインタを受け取ったとき、その文字列の終わりを NULL で判断するわけです。例えば、'a' という文字がいくつあるかをカウントする関数を作りたいとすると、配列の1番目、2番目と見ていき、'a' ならば、カウントを増やし、NULL が出るまでそれを繰り返すわけです。そうすれば、いくつ配列があるか(計算するデータはいくつか)という情報をわざわざ引数一つ作って関数に渡す必要がないからです。
NULL というのは、ASCII コードで0番です。char 型は1バイトですから、2進数で表すと "00000000" です。ちなみに文字としての数字の0は ASCII コードで48番です。同じく、2進数では "00110000" です。NULL は私たちが通常の生活で使っている文字のどれにもあてはまりません。よって、 NULL を文字として使うことはないので、「記号」としてつかるのです。詳しくは ASCII コード表を見て下さい。
int 型のデータは2進数で "0000000000000000" (2バイト)が0です。 よって、char 型以外では NULL を使って配列データの最後を表すことは出来ません。
念のため、またまたサンプルコードの登場です。下のように char 型配列が20個ありますが、配列の途中で NULL を入れているので、データはそこまでと判断されます。データは20個も出ないですよね?コンパイルして試して下さい。
配列の11番目に 0x00 がありますが、これが NULL です。0x が頭に着くのは「16進数の〜」と言う意味です。9までは10進数も16進数も同じですが、数字じゃいと言う意味をこめて(私は)char 型への代入はすべて、16進数でやってます。 「data = 0;」だと、data が int 型などの変数に見えてくるでしょ? C言語には沢山のライブラリ関数がついてきますが、すべて、この「文字列の最後は NULL 」を守っています。printf 関数だけではありません。
最後に文字と文字列の使い分けを説明します。え、何が違うんだって? 「列」のあるなしです。文字、文字列を表すとき、それは変数名では無いですよ、と言う意味を込めてクォーテーションでくくります。サンプルであれば、シングルクォーテーション「'」でくくっています。文字を表すときは、このシングルクォーテーションを用い、文字列を扱うときはダブルクォーテーション「"」でくくります。文字と文字列がどう違うのかと、最後に NULL がつくか、つかないかです。char 型のデータは配列一つで1バイトのデータを扱います。よって、
「文字列の終わりには NULL をつける」の意味をわたっていただけたでしょうか。次はいよいよ、文字列を char 型の配列データとして扱います。