それでは、chcnt.cの解説しながら、&を用いた引数から値を受け取るしくみ解き明かし
ましょう。
4行目の
void char_count(const char *str, int *alps, int *digs);
が自作関数char_countのプロトタイプ宣言です。
最初のvoidは、char_countは返す値がないことを意味します。
1つ目の引数の型は、charへのポインタです。ここで配列とポインタを同等に扱えることは、前回解説しました。「配列のように大きいデータを関数に渡すとき」にはポインタが使われます。
さらに続く2つの引数の型は、intへのポインタです。この場面は、「関数の引数から値(結果)を受け取りたいとき」で、ここでもポインタを使います。
次に関数呼び出しです。13行目の
char_count(str, &a, &d);
で、char_countが呼び出され、制御がchar_countに移ります。
ここでの1つ目の引数はstrで、これは「配列の先頭ポインタ」です。
続く2つの引数では、変数の前に & が付いています。この&は「アドレス演算子」と呼ばれるもので、オブジェクトへのポインタを求めるものです。ですから、&aは「変数aへのポインタ」、&bは「変数bへのポインタ」です。実はchar_countには引数が3つありますが、3つとも「ポインタ値」を渡しているのです。
さらに、18行目から31行目では、char_countが関数定義されています。18行目の
void char_count(const char *str, int *alps, int *digs)
では、文字列はstrが、英字の文字数はalpsが、数字の文字数はdigsが対応しますが、ここでポインタの機能が重要なカギを握ります。ポインタは「何か(オブジェクト)を指すもの」でした。ですからポインタを引数に渡すことで、下図のように、char_countの中からmainの中のオブジェクトを参照できるのです。
まとめると、「関数に対して変数の値を変更させるには、引数にその変数へのポインタ
を渡す」のです。呼ばれた関数からは、29行目と30行目のように、
*alps = acnt; *digs = dcnt;
間接演算子(*)を使って、ポインタの指すオブジェクトに値を代入するのです。
char_countで英字と数字の文字数のカウントは、23行目から28行目で行っています。これについては、問題11(文字列の長さと文字種類の判別)の解説を参考にしてください。
それでは、次回の宿題です。
基数変換する関数を作ってください。引数には基数変換する整数と基数、基数変換された結果を受け取る文字列の3つを使います。
⇒解答と解説は次回
Copyright © ITmedia, Inc. All Rights Reserved.