第4章 C言語の配列 ~intの配列とcharの配列~

 まず、char型の説明をしていないので、ひとまずchar型の変数について触れておきます。

 char型は、char letter; と宣言することで、一文字分の箱を用意する変数型です。 letter = ’a’; とシングルクォーテーションで囲んだ文字を代入した後、 printf(“%c”,letter); とすることで画面に文字を表示することができます。

#include <stdio.h>
void main ( )
{
        char letter;

        letter = 'a';

        printf("%c\n", letter);
}

 しかし、一文字ずつ使うことなんて普通はありません。 必ずと言っていいほど配列にして、長い文字列を表示するのに使われるものです。

 そういうわけで、配列の中でも最も重要な、char型の配列について説明していきます。 さっそく char型の配列を実際に使ってみましょう。 取りあえず、下のリスト10を打ち込んでみて下さい。

— リスト10 —

#include <stdio.h>
#include <string.h>  ←※関数strcpyを使うために必要になる

void main()
{
        char  str[41];   ・・・ (1)
        strcpy( str, "二つ目の引数を一つ目の引き数にコピーする" );    ・・・(2)

        printf( str );    ・・・(3)
        printf( "二つ目の引数を一つ目の引き数にコピーする" );    ・・・(4)
}

 まずは、一行一行説明していきましょう。

 (1)は、char型の配列を用意していますね。これで、文字列(文章)が入れられるようになります。

 (2)は、strcpy(string(英語で列の意味)をcopyするという意味)という関数を使って、 char配列に「二つ目の引数を...」を入れていってます。 strcpyはとてもよく使われる関数で、次の図のような働きを持っています。


— 図7 —

 (3)の printf は、皆さんのよく知ってる printf とはちょっと違いますね。 一つ目の引数が、「”」と「”」とで囲まれたものになっていません。 しかし、これでも全く違いはありません。引数が”二つ目の引数を…”であろうと、 “二つ目の引数を…”をコピーしたchar 配列の変数 str だろうと、同じ事になります。

 ここで、printf に渡す引数には、何故 [ ] が付かないのか疑問に思った人はいませんか? これは、先頭ポインタと呼ばれますが、とても難しいので今は説明しません。第7章で説明します。

 今のところ、[ ] を付けると配列の一つ一つを意味し、 [ ] を付けないと配列全体をあらわすなんて風に覚えて構いません(あくまでも、今のところです)。

 さて、今の説明を踏まえたうえで、さっそくコンパイルと実行をしてみて下さい。 おそらく、printf( ”二つ目の引数を一つ目の引き数にコピーする” ); と だけ記述した場合と、全く同じ実行結果になったはずです。 なんだかこれでは面倒臭いだけのようですね。

 「char配列なんて使う必要があるの?」なんて思ったかもしれません。 それでは次のリスト11に、軽く目を通してください。打ち込む必要はありません。

— リスト11 —

#include <stdio.h>
#include <string.h>

void main( )
{
        char  errorMsg[41];

        strcpy( errorMsg, "エラーが発生しました。処理を中断します。" );

        if ( ある処理でエラーが発生した場合 ) {
                printf( errorMsg );
        }

        if ( 別な処理でエラーが発生した場合 ) {
                printf( errorMsg );
        }

        if ( さらに別な処理でエラーが発生した場合 ) {
                printf( errorMsg );
        }
}

 errorMsgを何度も使いまわしていますね。 これは毎回毎回、printf( ”エラーが発生しました。 処理を中断します。” ); と記述しても構いません。

 しかし、「エラーが発生しました。処理を中断します。」を、 「エラーが起きました。処理を中断します。」に変えることになった時、 char配列を使っていないと三個所も修正しないといけません。 もっと大きなプログラムになった時には、何十個所も修正しないと いけないなんてことになるかもしれません。

 でも、上のようにchar配列を使ったプログラムにしておけば、 最初の一個所を修正するだけで良いのですから、とても楽ですね。 変更があった時に楽をできるプログラムにしておくのは、 良いプログラムを作る上ではとても大切なことです。

 それでは、char配列の説明を終わりにしましょう。最後に、一つ。

 ここまでに、リスト10とリスト11で、char 配列が二つ出てきましたね。 その時、どちらも配列を41個ほど用意してもらいました。 しかし、配列にコピーしたのは、何文字でしたか? どちらも20文字だったはずです。

 では何故、41個用意したのでしょうか?

 それは、日本語の漢字やひらがなを入れるには、 char一つでは入りきらなくて、charが二つ分必要だからです。 ですから、日本語20文字にはcharが40個必要なのです。

 では、おまけのように付いていた、もう一個([41]の1)は何のために必要なのでしょう?

 文字列の終わりには文字列終結文字(NULL文字)と呼ばれるものが、 かならず必要になります。 何故かというと、printf などの関数は、配列を引数にして渡されても、 どこまでが配列の終わりかわからないのです(「何でそんなのもわからないの?」と 思うかもしれません。しかし、その辺の説明は難しいので省きます)。

 そのためにprintf は、NULL文字が出てくることで、 文字列の終わりだと判断します(NULL文字がないと、 printfはいつまでも出力し続けしまいます)。 ですから、printf や strcpy に「”」と「”」で 囲んだ文字列を引数にして渡す時などは、 いつも自動的に最後にNULL文字を付けられていたのです。

 つまり、char配列を使う時には、いつもNULL文字分を 一つ余計に用意することが必要なのです。 これを忘れるとたいへんなことが起きてしまいます!

 文字列について、わかりましたか?

 文字列についてまだピンとこない人は、次のようなプログラムを作って試してみて下さい。 これは、先ほど出てきた関数 strcpy を自作するプログラムです。

— リスト12 —

#include <stdio.h>
#include <string.h>

void main()
{
        char  str[6];   /* 自作strcpyの文字列コピー元 */
        char  buf[6];   /* 自作strcpyの文字列コピー先 */
        int   cnt;     /* ループカウンター      */

        strcpy( str, "abcde" );

        /**
         * strcpy を自作する
         * ・NULL文字でない間、ループし続ける
         * ・順に1文字づつコピーする
         * ・最後にNULL文字をコピーする
         */
        for( cnt=0; str[cnt] != '\0'; cnt++ ){
                buf[cnt] = str[cnt];
        }
        buf[cnt] = '\0';

        /**
         * strcpy と、自作した strcpy の違いを確かめる 
         */
        printf( "文字列 str = %s\n", str );
        printf( "文字列 buf = %s\n", buf );
}

 さぁ、今日はかなり難しいことがいっぱい出てきましたね。 ここで一度、頭を整理しておきましょう。 わからないことがあったら、講師に質問して下さい。

< 前のページへ

Pagetop