2001年後期 情報処理演習I (火曜1限)
■ 情報処理演習I
■ 講義(7)
■ 講義(8)
■ 講義(9)
■ 講義(10)
■ 講義(11)
■ 講義(12)
■ C言語入門(1)
■ C言語入門(2)
C言語入門(2)

関数の定義

今まで main 関数の中に全てのプログラムを書いてきたが,これでは複雑なプログラムを書くことができない.複雑なプログラムは,プログラムの処理を複数の関数に分割して記述する.

関数は,何らかのまとまった処理を行う単位である.関数を定義すれば,その関数を呼び出すことによって,簡単に処理を行わせることができる.関数を呼び出すことを関数呼び出しと言う.

  • printfやscanfは,予め用意されている関数.
  • 自分で定義した関数は,printfやscanf等の予め用意されている関数と 区別すること無く使うことができる.
  • 関数には,引数を渡すことができる.引数によって,関数にどのようなことをさせるのかを細かく指定する.

    例えば,printf関数では,引数によって何を表示するのかを決めている.

  • 関数は,return 文を使って値を返すことができる.返す値を返り値と呼ぶ.返り値は,関数が処理を行った結果を呼び出し側に報告するために使う.

    例えば,random関数は処理の結果(乱数の値)を返り値として返している.

関数の書き方

C言語では,関数を以下のように書く.

返り値の型
関数名(引数の並び)
{
        関数の本体
}

例えば,整数の絶対値を求める関数は以下のようになる.引数として int 型の整数を受取り,その絶対値を返り値として返している.

/*
 * 絶対値を求める関数 absolute
 */
int
absolute(int a)
{
        if (a < 0) {
                return -a;
        } else {
                return a;
        }
}

関数を使った場合のプログラムの実行のされ方

■ このファイルをダウンロード
(右ボタンでクリックして「リンク先を名前をつけて保存」する)

#include <stdio.h>

int
add(int a, int b)
{
    return a + b;
}

main()
{
    int a;
    a = add(10, 20);
    printf("10 + 20 = %d\n", a);
}


もうちょっと複雑な例

■ このファイルをダウンロード
(右ボタンでクリックして「リンク先を名前をつけて保存」する)

#include <stdio.h>

/* 整数 a から b までの和を int 型で返す関数 sum の定義 */
/* 2つの int 型の引数をとる */
int
sum(int a, int b)       /* a と b に,この関数を呼び出した時の引数が入ってくる */
                        /* 普通の変数と同じように使える */
{
        int i;          /* main 関数と同じように,ここでも変数を宣言できる */
        int s;          /* ここで宣言した変数は,この関数の中だけで使える */
                        /* 他の関数に同名の変数があっても,影響を与えない */
        s = 0;
        /* a や b は,通常の変数と同じように使える */
        for (i = a ; i <= b ; i++) {
                s = s + i;
        }

        return s;        /* return文で計算した値を返す */
}

/*
 * 書いた順番に関わらず,Cのプログラムは main 関数から実行される
 */
main()
{
        int a;
        int i;

        /* 定義した関数を利用する例 */
        a = sum(1, 10);
        printf("1 から 10 の和は %d です\n", a);

        for (i = 1 ; i < 10 ; i++) {
                printf("%d から10の和は %d です\n", i, sum(i, 10));
        }
}


注意
  • return 文は複数書いても良い.実行中に return 文に出会うと,関数の実行は終了する.
  • 関数から関数を呼び出しても良い.
  • 引数が不要な場合,引数として void を書く.
    int
    foo(void)
    {
            関数の本体
    }
    この関数を呼び出す側は,foo(); と書く.
  • 返り値が不要な場合,返り値の型として void を使う.この場合 return 文には値は不要.
    void
    foo(int a, int b, int c)
    {
            関数の本体
    }

    何らかの処理を行うものの,その結果を呼び出し側に報告する必要がない場合に,このような void 型の関数を使う.

  • 異なる関数の中に,同じ名前の変数があっても,別々のものとして扱われる.このため,関数を呼び出す側は,呼び出した関数によって自分の変数が書き換えられてしまうという心配をしないでよい.
  • 関数の実行が終了すると,その中で宣言した変数は消滅する.次に呼び出した時には,前回の値は残っていない.

棒グラフ

引数で指定された数だけ画面に * を表示し,最後に改行する関数 print_bar を書け.print_barの返り値は不要(void).

main 関数は,キーボードから数値を読み込み,それを引数としてprint_bar を繰り返し呼び出す.この処理を利用者が0を入力するまで続ける.

実行例

Number: 5
*****
Number: 20
********************
Number: 0

プログラムの構造

/* n 個 * を表示し,最後に改行する関数 */
void
print_bar(int n)
{
        /* ここを埋める */
}

main()
{
        int num;

        for (;;) {
                printf("Number: ");
                scanf("%d", &num);
                if (num == 0) {
                        break;
                }
                print_bar(num);
        }
}

ヒント

  • * の表示は printf("*");

演習

次のような図形を書く関数 triangle を書け.* の表示には上で書いた print_bar を使うこと.triangle は引数として行数をとる.返り値は不要(void).

triangle(5)の実行例

*
**
***
****
*****

テストするために main 関数も作成し,利用者が数を入力すると,その数を引数として triangle を呼び出せ.この処理を0が入力されるまで続けよ

Number: 3
*
**
***
Number: 5
*
**
***
****
*****
Number: 0

プログラムの構造

/* n 個 * を表示し,最後に改行する関数 */
void
print_bar(int n)
{
        /* 上の問題と同じ */
}

/* n 個 * を表示し,最後に改行する関数 */
void
triangle(int n)
{
        ....
}

main()
{
        ....
}

問題

キーボードから,0〜99までの数をいくつか入力する.(最大10個まで).10個目を入力したか,0 を入力した後,値と棒グラフを入力した順番に書くプログラムを書け.

実行例

number? 10
number? 1
number? 4
number? 8
number? 0
10: **********
 1: *
 4: ****
 8: ********

まず,数値を2桁で右寄せして表示し,その右に棒グラフを表示する関数 print_bar_num を作成せよ.print_bar_num関数は print_bar を呼んで棒グラフを表示する.

print_bar_num(10);の実行例

10: **********
ヒント
  • 2桁右寄せで表示するには printf で "%2d"
  • main関数では配列を使って入力した値を覚える.いくつ入力したかも数える必要がある
k-abe@media.osaka-cu.ac.jp