関数

これまで作成したプログラムは非常に簡単なもので数10行のコードで作成できました。
しかし、複雑なアプリケーションとなると数千行、数万行といった膨大なソースコードが必要になってきます。
if文やfor文を駆使すれば、今の作りでもそのようなアプリケーションを作成することは不可能ではありませんが、いささか現実的ではありません。
また、プログラムを組んでいくと同じような処理を繰り返して実装することが多々あるでしょう。
このような問題を解決する為に、関数(Function)という仕組みがあります。

実は我々は既にmain関数と呼ばれる関数を使用しています。
main関数は今までオマジナイとして書かれていた次の部分を指します。

int main(int argc, char *argv[])
{
}

このmain関数は特別な関数で、プログラムがコンパイルされ実行される時に最初に実行が開始される部分(エントリーポイント)としての役割を果たします。
逆に言えば、main関数のないプログラムは実行できません(コンパイルもできません)。

ユーザー定義関数

C言語には標準関数と呼ばれる関数とユーザー定義関数と呼ばれる2種類の関数があります。
「printf関数」は標準関数の1つで、文字列を標準出力に出力することができます。
これらの標準関数はデフォルトで使用できる共通機能でありどのような関数がありどんな動作をするかは決まっていて変更することはできません(厳密には言語仕様とコンパイラの実装によります)。

それに対して、ユーザー定義関数はプログラマが自由に定義できる関数です。
次のプログラムは、2つの整数に対して掛け算を行う関数「calc」を作成した一例です。
[example06.c]

#include <stdio.h>

int main(int argc, char *argv[])
{
    int x = 12;
    int y = 3;
    int z = calc(x, y);
    printf("%d * %d = %d\n", x, y, z);
    return 0;
}

int calc(int a, int b)
{
    return a * b;
}

関数の引数と戻り値

関数は「関数名」「引数」「戻り値」の3つの要素から構成されます。

引数

引数(ひきすう)とは関数に渡す値です。
calc関数では掛け算を行う整数を2つ定義しています。
ここで注意しなくてはならないのは、mainのx,yとcalc関数のa,bは別のメモリ領域に確保されるということです。
x,yはそれぞれint型として宣言されてメモリに確保されますが、calc関数が実行されるとa,bを別途int型としてメモリに確保し、x,yの値がコピーされます。
従って、次のように書いたとしても、x,yの値が変わることはありません。

int calc(int a, int b)
{
    a = a + 1;
    return a * b;
}

ですが、「12 * 3 = 39」と表示されるでしょう。
また、次のように書いても問題ありません。

int calc(int x, int y)
{
    return x * y;
}

calc関数ではx,yを独自にメモリに確保している為、mainで宣言されたx,yとは別物であるからです。

戻り値

戻り値は関数の返す結果です。
calc関数は計算結果をint型で返す関数です。
戻り値の型は1つしか定義できません。

関数はその最後にreturnという制御構文で値を返します。
当然ですが、関数で定義した型を返さなくてはなりません。

関数名

関数名は変数名と同じようなプログラムでの関数の名前です。
calc関数は「calc」という名前を持っており、変数と同様に同じ名前の関数を作ることはできません。
もし、足し算の関数を追加したいのであれば、calc関数では名前が重複してしまう為にadd関数のように定義する必要があります。


関数は以下の形で記述します。

戻り値型 関数名(引数1の型 引数名1, 引数2の型 引数名2, ・・・)
{
    // 処理
    return 戻り値;
}

明日は構造体のお話です。