関数

機能の分離としての関数

長いプログラムは内容の把握が難しくなります。機能や処理を分割することで見通しをよくすることができます。

この分割された機能を言語によりいろいろな呼び方をします。サブルーチンとかあまり使われない訳語として副プログラムとか、ファンクション、メソッドなどです。さらに言語によっては値を返すものと作業をするだけのものと別の名前で呼ぶものがあります。C言語では「関数」しかありません。名前は値を返すような名前ですが、作業するだけでも何かを返しているからです。

関数の形

基本形です。[ ]は省略可能をあらわします。

[返り値の型] 関数名( 型 引数 [,型 引数...] ){
        文
        ...
}

具体例です。2つの整数値を受け取って和を返す関数です。

int wa(int x,int y){
    int s;
    s = x + y;
    return s;
}
返り値
C言語の関数はなんらかの値を返すのが普通です。上の例の様に計算結果であることもあれば、作業がうまく行ったら0、そうでなければ 1 などとする場合もあります。上の具体例では s がそれです。
関数名
変数の名前と同様に英字で始まる英数字の組み合わせにします。上の具体例では wa がそれです。
引数
関数を呼び出す側から関数に与えるデータの型と、関数内でそのデータが格納される変数名を必要なだけコンマで区切って並べます。ここで宣言される変数や関数内で宣言する変数は関数内だけで有効です。たとえ呼び出す側に同じ名前の変数があっても別なものとして扱われます。上の具体例では x と y がそれです。

課題7-1 関数の定義の基本形

プログラム名 k0701.c

 1: /* 関数の定義の基本形 k0701.c */
 2: #include <stdio.h>
 3: 
 4: int wa(int x,int y){
 5:     int s;
 6:     s = x + y;
 7:     return s;
 8: }
 9: 
10: int main()
11: {
12:     int a=100;
13:     int b=20;
14:     int c = wa(a,50+b);
15:     printf("%d\n",c);
16:     return 0;
17: }

プログラム解説 k0701.c

4:-8: wa()
上の具体例で説明した、2つの整数値を受け取って和を返す関数です。
10: main()
ブログラムはいつもmain()から始まります。
14:
a と 50+b の2つの整数を入れて wa() を呼びだします。a の値の 100 が x に、50+b の値の 70 が y にそれぞれ代入されます。
変数でも数値でも計算式でも整数であれば正しく伝わります。
wa() からは足し算の結果の 170 が帰ってきます。これが戻り値です。これを変数 c に代入します。
15:
C の値を表示します
16:
実はC言語のプログラムは全体が関数として実行されています。実行が問題なく行われたら 0 を返します。これが return 0 です。

実行結果はこうなります。

~/c$ ./k0701
170

課題7-2 戻り値を使わない関数の呼び方

k0701.cに比べて色のついた部分が異なっています。

プログラム名 k0702.c

 1: /* 戻り値を使わない関数の呼び方 k0702.c */
 2: #include <stdio.h>
 3: 
 4: int wa(int x,int y){
 5:     int s;
 6:     s = x + y;
 7:     printf("%d\n",s);
 8:     return s;
 9: }
10: 
11: int main()
12: {
13:     int a=100;
14:     int b=20;
15:     wa(a,50+b);
16:     /* printf("%d\n",c); */
17:     return 0;
18: }

プログラム解説 k0702.c

7: printf("%d\n",s);
関数の側で表示をするようにしました。
8:
関数では値をreturnで戻していますが、これは使われることはありません。。
15: wa(a,50+b);
wa() の戻り値を利用していません。代入の式でなくなっていることに注目してください。。
16: //printf("%d\n",c);
消してしまってもいいのですが、次の課題で戻すのでコメントにしました。コメント文はコンパイルで無視されます。

実行結果は同じです。

~/c$ ./k0702
170

課題7-3 変数の有効範囲(スコープ)

k0701.cに比べてこの色のついた部分この色のついた部分が異なっています。同じ名前の変数でも関数が異なれば別扱いであることを確かめています。

プログラム名 k0703.c

 1: /* 変数の有効範囲(スコープ): k0703.c */
 2: #include <stdio.h>
 3: 
 4: int wa(int a,int b){
 5:     int s;
 6:     s = a + b;
 7:     a = 0;
 8:     printf("wa()の中では..\n");
 9:     printf("a=%d\n",a);
10:     printf("b=%d\n",b);
11:     printf("s=%d\n",s);
12:     return s;
13: }
14: 
15: int main()
16: {
17:     int a=100;
18:     int b=20;
19:     int s=3;
20:     int c=wa(a,50+b);
21:     printf("main()に戻って..\n");
22:     printf("a=%d\n",a);
23:     printf("b=%d\n",b);
24:     printf("c=%d\n",c);
25:     printf("s=%d\n",s);
26:     return 0;
27: }

プログラム解説 k0703.c

4: int wa(int a,int b)
main() 内とおなじに a,b の名前の変数を宣言していますが、wa()の中だけに有効な変数になります。main()の a,b には影響を与えません。
7: a = 0;
丁寧に a の値を変更していますが、こちもmain()の a の値に影響しません。
8:-11:
wa()の中の変数の値を表示しています。同じ名前の変数でも独立だということを確認するためです。
a の値は 0 を代入、b は main()から 50+b という値を伝えられているので70です。s は a が 100 のときに a+b を代入しているので、170 です。
21:-25:
wa()の中の変数の値を表示しています。同じ名前の変数でも独立だということを確認するためです。
a の値は wa() を呼ぶ前の 100 。b も元のまま 20 。c はもちろん返り値なので 170 。s は新規に 3 としたので 3 のまま。

実行結果はこうなります。

~/c$ ./k0703
wa()の中では..
a=0
b=70
s=170
main()に戻って..
a=100
b=20
c=170
s=3
聖愛中学高等学校
http://www.seiai.ed.jp/
Oct. 2011