第六話 引数についてもっと詳しく
翌日の午後。
俺は例によって部室へと入って行った。扉を開けて中を見ると、立花先輩は既に部室に来ていて、PCで何か作っている最中のようだった。
「あっ。イツキくん。今日も御苦労」
顔だけ振り向いて笑顔を見せる。
「先輩、ちーっす」
俺は片手をあげて軽く返事すると、PCへと近づいて行った。
「なに作ってるんですか?」
「うん。昨日のね、引数の説明じゃ、イツキくん、よくわからなかったんじゃないかなーって思って」
どうやら、別のプログラムを書いている最中だったようである。
カタカタ、と打ち込んで、「よし、できた」と先輩は呟いた。
「イツキくん、見て見て。今度のコード」
「どれどれ――」
俺はモニターを覗き込んだ。
/* 足し算プログラム calcprogram.c */
#include <stdio.h>
/* 計算する関数。int型の引数aとbを取って、int型の結果resultを返す */
int calc(int a, int b)
{
int result;
result = a + b;
return result;
}
int main(void)
{
int a;
int b;
int result;
a = 1;
b = 2;
result = calc(a,b);
printf("1 + 2 = %d だよー\n", result);
return 0;
}
今度のは、二つの関数があった。mainの方は、前にも見てるんだが。
「calc関数、ですか?」
「うん。calculation。計算する目的の関数、作ったの。関数って、こういう風に自由に自作できるのよ」
「英語かぁ……。先輩、Cは日本語使えなくても、せめてKEISANとかの名前の方が解り易くないですか?」
「ん…っ…そ、それは、ちょっと恥ずかしい、かも…」
先輩、妙なところで気にするんだな。
「とにかくっ。じゃあ、ちょっと動かしてみるわよ」
先輩は、コマンドプロンプトでコンパイル命令をする。
c:¥sample>gcc -Wall -o calcprogram calcprogram.c
c:¥sample>calcprogram
1 + 2 = 3 だよー
c:¥sample>_
「ふむ。当たり前か」俺は呟く。
「これくらい単純な方が、イツキくんにも解りやすいでしょ? じゃ、コードの解説に戻るわよ。このプログラムのポイントは、main関数とcalc関数の引数、戻り値のやりとりね。まずmainから見てみるわよ」
「int aとかbとかって?」
「あ。これは、変数っていって、aの中に自由に数字を入れておく箱だと思って。前にも言ったけど、int型で宣言しているから、整数しか入らないわよ。小数点入りの数字入れたらエラーになるわ」
「変数、か」
「次のa = 1で、aという名前の箱の中に、1の数字を入れておくって意味。bには2ね。変数には自由に数字を入れたり、読みだしたり出来るの」
「result = calc(a,b); というのは、result変数に……」
俺はつまった。うーん、難しい。
「calc(a,b)関数で計算した戻り値が入るのよ」先輩が助け舟を出す。「resultって結果って意味でしょ?」
「ああ、なるほど」
「で、printf()関数で結果表示。ここの、%dって書いた部分に、変数の数字が表示できるの。この場合、result変数がそれね」
「うーむ。まあ、mainの方はわかりました」
「でね、calc関数の方に移るけど、こちらではint型のaとbの変数を受け取って、中で計算してから、result変数を戻すの」
「見たまんまですね……」
「でも、ここで気をつけるのは、この関数内のaやb、resultは、実はmain関数内のa、b、resultとは何の関係もないことよ。それぞれ、別の変数として扱われてるの」
「ん? どういう事です?」
「つまりね、一つの関数内で宣言された変数、これはローカル変数って呼ぶんだけど、その関数の中でしか『見えない』のよ。正確に言うならば、{}のカッコの中でしか、なんだけど――。たとえ同じ名前の変数が呼び出した側にあっても、一切関係ないの」
「ごめん。よくわからん……」
「うーん。なら、こうしたら、解りやすいかな」
立花先輩は、カタカタとキーボードを打って、プログラムを書き換えた。
/* 足し算プログラム calcprogram.c */
#include <stdio.h>
/* 計算する関数。int型の引数xとyを取って、int型の結果zを返す */
int calc(int x, int y)
{
int z;
z = x + y;
return z;
}
int main(void)
{
int a;
int b;
int result;
a = 1;
b = 2;
result = calc(a,b);
printf("1 + 2 = %d だよー\n", result);
return 0;
}
「calc関数の引数の名前をx,y。戻り値に使う変数をzに変えてみたわ。これでも、何の問題もなく動くの」
「うーむ。ちょっと、解かりかけてきたかな」
「じゃあ、これじゃあ、どう? また、コードの流れを書くわよ」
先輩は、カリカリとコードの隅に書きこむ。
Windows OS
↓ calcprogram.exeを実行するぞー。以下略。
main()関数
↓ int型の変数a,b,resultを宣言して、次にaに1、bに2の数を入れる。
resultには……あ、その前にcalc(a,b)関数が書かれているから、そっち先に実行しよ。aは1、bは2だから、calc(1,2)として呼ぼう。
calc(int x,int y)関数
↓ mainから呼ばれたわ。引数は1と2か。なら、ウチの変数xとyに、x = 1, y = 2として入れておこう。
計算して、変数zに結果を入れたら、これを戻り値として返すよー。でも、return zのzは先に3として計算されるから、main関数は知らないけど。
main()関数
↓ 戻り値で3が返ってきたわ。z変数? なにそれ?
じゃあ、返ってきた3の数を、result変数へ入れて、printf()関数を呼ぼう。引数は"1 + 2 = %d だよー\n"の文字列と、result……これは、3として先に計算されるから、実際は3。この二つね。
printf()関数
↓ 表示するよー。以下略。
main()関数
↓ では、うちもreturn 0で戻ります。
Windows OS
戻ってきました。戻り値は0なら問題なしね。このcalcprogram.exeは、これで終了。
「と、こんな感じ。文章にすると、長いわね……」
「あ、でも、よくわかりました」
「そう言ってくれると、嬉しいわ」先輩はにこっと笑った。
「最後に付け加え。main()関数の呼び出す方での引数、calc(a,b)のaやbのことを実引数って言って、calc()関数側でのint calc(int x, int y)のxやyは仮引数って呼ぶの。よく本とかじゃそう書いてあるから、間違わないように気をつけてね」
「ところで、このプログラム、1 + 2 しか出来ないんですか?」
それじゃ意味ねーよ。
「うん。コードの中のa = 1とb = 2の所を書き換えたら、他の計算も出来るけど、計算のたびに、いちいちコンパイルするのも馬鹿らしいわね。じゃ、次には、数を入力するプログラムを作ってみるわよ」
そう言うと立花先輩は再びコードを作り始めた。