娘のためにその6:返り値[30分]

娘に読ませる以外の意図はなく、よって質問や指摘には対応していません。すなわちネットの浄化作用が働いていない不正確な内容になりますので、正しい情報を求める方は閲覧をご遠慮ください。公開しているのは、通信手段としての利便性のためです。
void ffff()
{
   int a = 100;
   int b = a * 20;
   int c = a * b;
}

これまで説明に使用してきたこのプログラムは、実はまったく意味をなさないものだった。実行しても何も起きないのだ。

int ffff()
{
   int a = 100;
   int b = a * 20;
   int c = a * b;
   return c;
}

このように書き換えると、意味をなすようになる。変更点は二箇所。

まず、関数 ffff の前、これまでは void と書かれてあのを int にした。

次に、return c; という行を追加している。

ひとつずつ見ていこう。そもそも void というのは「この関数は返り値を返さない」という意味だったのだ。これを int にしたことで「この関数は int 、つまり整数を返り値として返す」という意味になった。これまでたびたび int というコトバが登場していたが、それは「整数」を意味する型の名称だった。そしてこの宣言通りに返り値を返すため、 return c; という記述が加わった。「関数 ffff の返り値はintである」のように表現する。

この変更をするまでは、関数 ffff を実行しても、中で計算をしていたとしても、その結果が外に出ることはなかったため、無意味だった。返り値を返す記述をしたことで、意味が生まれた。呼び出し側に返り値を返すことができるようになったのだ。

void gggg()
{
    int v = ffff();
}

int ffff()
{
   int a = 100;
   int b = a * 20;
   int c = a * b;
   return c;
}

上の例では関数 gggg の中で ffff を呼び出し、その返り値を v という変数に格納している。ffff の計算結果が v という変数に格納されたわけだ。これで初めて、ffff の計算結果が活用されるようになった。

では、void をつけた関数はすべて無意味なのだろうか?そんなはずはない。void の関数を用意するのは、どんな場合に意味があるのだろうか?

void setup()
{  
    Serial.begin(9600);
    Serial.println("hello");
}

この関数に見覚えがあるだろう。これにはコンソールに文字を出力するという意味があった。つまり void 関数は返り値を返さない代わりに、「関数の外側に影響を与える」記述が必ず含まれている。それはメモリだったり、ファイルだったり、サウンドだったり、グラフィクスだったり、この例のようにコンソールだったりする。このように関数の外側に影響を及ぼすことを、プログラム用語で「副作用」と言う。

副作用、のように、プログラム上の状況に名前がついている例がけっこうたくさんある。名前なんてどうでもいい、などと思うことなかれ。プログラマ同士の会話はこういった名前抜きでは成立しない。とくに「副作用」は重要な概念なので、ここで覚えておきたいところだ。すごくざっくりした言い方をすれば、副作用のある関数はバグを誘発しやすい。いわゆるスパゲッティプログラムというのは大抵はそういう形をしている。副作用のない関数ばかりで構成されたプログラムは保守しやすい傾向がある。副作用については今後も触れる機会があるだろう。

返り値がわかったところで、次に引数について解説しよう。

void gggg()
{
    int v = ffff(100);
}

int ffff(int a)
{
   int b = a * 20;
   int c = a * b;
   return c;
}

ffff の定義に (int a) というのが加わった。() の中に型と変数を記述すると、それが引数(ひきすう)の意味になる。gggg で ffff を呼び出す際に ffff(100); のように数値を与えているのにも注目して欲しい。これが引数を渡している事になる。

なぜプログラムの実行単位を「関数」と呼ぶか。そもそもは、数学の関数と同じ意味があるからだ。

f(x)=2x+1

という「数学的な」関数があったとしよう。これをプログラムで記述すると

int ffff(int x)
{
    return 2*x + 1;
}

こうなる。呼び出す側は

void gggg()
{
    int y = ffff(100);
}

のようになる。y に何が入るか予想してみよう。プログラムを書いて、実行して y を Serial.println(y); などで表示して動作を確認してみよう。プログラムで関数、と呼ばれるものが数学で言うところの関数と同じ働きをすることが実感できるだろう。

次の動画は、ここまでの話を理解したタイミングで見るのがちょうどいいはずだ。10分。

プロなら当然! プログラミング技能解説 1. プログラム言語 https://learning.unity3d.jp/2077/

この動画では言語にC#(シーシャープ)というUnityで採用している言語を例に解説している。書いたプログラムがどう解釈されるのか、という話はあらゆる言語に共通だ。C#はC言語から派生した言語で、Unityが採用している言語だが、多くの部分においてC言語と共通なので、この動画の範囲なら戸惑うこともないだろう。

つづく

この記事が気に入ったらサポートをしてみませんか?