第5回:関数

先週に引き続き関数を取り上げます.


先週の演習のこたえ

三角形

レベル1:三角形の底辺の長さと高さを入力する時,面積を求めて戻す関数を作成せよ

#include <stdio.h>

float sankaku(int a, int b) 
{
    float s;

    s = a * b / 2.0;

    return s;
}

void main()
{
    int a, b;
    float s;

    printf("三角形の面積を求めます\n");
    printf("底辺の長さを入力してください:");
    scanf("%d", &a);
    printf("高さを入力してください:");
    scanf("%d", &b);

    s = sankaku(a, b);        //関数を呼び出す

    printf("三角形の面積は,%fです.", s);
}

値参照(Call by value)

このプログラムでは,main関数からsankaku関数へ変数の値(中身)が渡されています.これを値参照(Call by value)といいます. 値参照では,関数を呼びだした元の変数は変化しません.元の関数に結果を返すにはreturn文を用います.このため,戻り値はひとつです.

簡単なプログラムで確認してみましょう.

#include <stdio.h>

int test(int a) 
{
    a += 10;

    return a;
}

void main()
{
    int a, b;

    printf("aの値を入力してください:");
    scanf("%d", &a);

    b = test(a);

    printf("aの値は%d\nbの値は%d\n", a, b);
}

aに2を入力すると,結果はどのように表示されるだろう.


これまでは,一つの値しか関数から戻すことができなかった.また,同じ変数名を使っていても,関数の方で値を変えても,mainでは変化しなかった.これは,関数には変数の中身が伝えられているためです.

では,関数に変数をしまってある場所を伝えたらどうなるだろう.


アドレス参照(Call by reference)

変数のしまってある場所(アドレス)を扱うには,ポインタの出番です.

上のプログラムで確認してみましょう.

#include <stdio.h>

int test2(int *a)        //変数aのアドレスを受け取る(ポインタ変数)
{
    *a += 10;        //aの指すアドレスの中身に1を加えるから,main関数でも変化する

    return *a;
}

void main()
{
    int a, b;

    printf("aの値を入力してください:");
    scanf("%d", &a);

    b = test2(&a);        //変数aのアドレスを関数に渡す

    printf("aの値は%d\nbの値は%d\n", a, b);
}

aに2を入力すると,結果はどのように表示されるだろう.


演習

(関数の練習)よく使う関数を用意しておこう.

1.二つの整数を渡すと,大きい方を答える関数
2.整数の2乗を計算する関数
3.整数の3乗を計算する関数
4.整数のn乗を計算する関数
5.整数の階乗を計算する関数

main関数の部分はこんな感じ.あとは,関数の定義部分を作ってみよう.

void main()
{
    int a, b, n;

    printf("aの値を入力してください:");
    scanf("%d", &a);
    printf("bの値を入力してください:");
    scanf("%d", &b);
    printf("n乗のnの値を入力してください:");
    scanf("%d", &n);  

    printf("大きい数の値は%d\n", large(a, b));
    printf("aの2乗は%d\n", square(a));
    printf("bの3乗は%d\n", cube(b));
    printf("aの%d乗は%d\n", n, power(a, n));
    printf("bの階乗は%d\n", factorial(b));
}

(アドレス参照の練習)

円の半径を入力すると,円の面積と円周の長さの二つの値を返す関数を作ってみよう.

ヒント:値を返してもらう場所も,関数に伝える必要がある.