関数

型と処理範囲を説明したところで,関数をより詳細紹介する.数学で言うところの関数といえば,y = f(x)と書いたときのfのことで,この場合 ( ) の中に値を指定して,それに対する関数の値として y の値が定まるというものである.C++ でも同様に,値を与えて別の値を取得するという用途に関数を使う.このために,値を受け取る仕組みと,値を関数が使われた場所に返す仕組みが必要となる.

関数は,想定される値には,一つだけではなく対応しなくてはならない.この想定される値を受け取る変数を仮に仮定して,C++ では次のように関数を定義する.返す値は return で指定する.

int f(int x){
    return x*2;
}

いくら渡される値がわからないと言っても,その型だけは確定しているとC++では規定されている.上記のように,渡されると想定される値の型と値を実際に受け取る変数を ()の中に記載し,返す予定の型を関数名の前に記載する.実際に関数を用いるコードの例を以下に示す.

#include <iostream>

int f(int x){
    return x*2;
}

int main(){
    int y;
    y = f(2);
    std::cout << y << '\n';
}

ファイルをf.cppとして保存してコンパイルから実行まで行った結果を以下に示す.引数を2倍して返す関数をfは意図しているが,それに従った結果が得られている.

shibata@ShibataD:~/git/cpp$ g++ f.cpp shibata@ShibataD:~/git/cpp$ ./a.out 4

このreturn に指定する値を戻り値という.また,3行目で渡される値を受け取る変数のことを仮引数という.値が渡される前から,ここに定義された変数に値が渡されると仮定して処理を記述するところから,この名前となっているのだろう.9行目では,実際に2という値を与えて関数からyの値を定めている.この2のような実際に与える値のことを実引数という.

実引数に,変数を指定することも可能である.以下に例を示す.f の内容は仮引数の値を変更して,return に指定するというものに変更されている.

#include <iostream>

int f(int x){
    x = x + 2;
    return x;
}

int main(){
    int y;
    int z = 3;
    y = f(z);
    std::cout << y << '\n';
    std::cout << z << '\n';
}

実行結果を以下に示す.

shibata@ShibataD:~/git/cpp$ g++ f.cpp shibata@ShibataD:~/git/cpp$ ./a.out 5 3

この結果より,実引数に指定した変数の値は,仮引数 x に対する操作の影響を受けないことがわかる.C++では実引数に変数が渡された場合,その変数の値を取り出して仮引数の変数へ渡してから関数の処理を実行する.よってこのような動作になっている.

引数の数はいくつでもよく,また,型の制限もない.以下に例を示す.

#include <iostream>

float f(int x, double a){
    double r = x + a;
    return r;
}

int main(){
    float y;
    int z = 3;
    y = f(z, 1.12);
    std::cout << y << '\n';
}

また,次の通り関数の中で別の関数を使っても構わない.

#include <iostream>

float g(double a){
    return 1.3*a;
}
float f(int x, double a){
    double r = x + a + g(x);
    return r;
}

int main(){
    float y;
    int z = 3;
    y = f(z, 1.12);
    std::cout << y << '\n';
}

関数を使うことを,関数を呼び出す,と普通言う.関数へ処理を転送するというのが動作の解釈では正しいはずだが,関数の方から来てもらうことを意味する,呼ぶ,という表現を使うのである.理由はよくわからない.