第11章の1 関数の基本

1. 関数とは

Cプログラムは「関数」という小さなプログラムの集まりで構成されます。 main() も実は関数ですし、printf() や scanf() も関数です。
この章では、「ユーザ関数」と呼ばれる、製作者側で作成する関数について学習します。

2. 関数の基本

ある規模以上のプログラムを main関数だけで作成すると、ステップ数の多い理解しにくいプログラムができあがってしまいます。 ですから、プログラムはいくつかの関数に分けて作成する方が、コンパクトで理解しやすいものとなります。 また、同じような処理を複数の個所で行っている場合、関数としてその処理をまとめてしまうと全体のステップ数も減ることになります。

(1) 関数を用いた場合の処理の流れ

まず、関数を用いた場合、プログラムはどのような順番で実行されるのかを下図に示します。 下図では main()から wa() という関数が呼ばれるようになっています。

  1. main()の先頭から wa()までを実行。
  2. wa()に処理が飛ぶ。このとき wa()にデータ a, b を渡す。これを実引数(じつひきすう)と呼ぶ。
  3. wa()は渡された a, b を x, y に代入して処理を実行。この x, y を仮引数(かりひきすう)と呼ぶ。
  4. main()関数に戻る。このとき、データzの値を返す。このzを返却値(または戻り値)と呼ぶ。
  5. リターン値を sum に代入して、main()の残りを実行。

(2) 関数の使用例

次に実際に上の例をプログラムで記述してみます。

このように、関数を使用する場合には、

  1. ユーザ関数のプロトタイプ宣言を main関数 よりも前に記述する。 この宣言は、コンパイラに関数の情報を与える。 この宣言を行うとコンパイラは関数の引数と返却値のチェックを行う。
  2. main関数の中(ユーザ関数の中でもよい)で、ユーザ関数を呼ぶ。
  3. main関数に続けてユーザ関数の本体部を記述する。 (ユーザ関数を別ファイルとして作成する場合もありますが、このサイトでは扱いません。)

(3) 各部の説明

プロトタイプ宣言、関数定義、return、void について説明します。

プロトタイプ宣言

コンパイラに、関数名、return型、引数の型を知らせる

返却値型 関数名(引数型と仮引数名の並び);

  • (例)double wa(double x, double y);
  • 関数名の名付け方については第2章を参照のこと。
  • リターン値が無い場合は、return型はvoidとなる。
  • 返却値型を省略すると、型は「int型」となる。
  • 引数がない場合は関数名(void)とする。
  • セミコロンを忘れないこと。

関数定義

関数の本体(処理内容)を記述し、実際にメモリ領域が割り当てられる。

返却値型 関数名(引数型と仮引数名の並び)
{
  関数内変数の宣言
  実行文
  return文;
}

  • 返却値が無い場合は、返却値型はvoidとなる。
  • 引数がない場合は関数名(void)とする。

return

  1. 値を返す必要があるとき
    return 値; が一般的
    return 式; 直接式でも可
  2. 値を返す必要のないとき
    return;

    ※ 値を返す必要のない、2.の「return;」は関数の最後でリターンする場合は通常省略されます。
      ただし、処理の途中でリターンする場合は省略はできません。
      なお、省略した場合には、関数終了の } でリターンします。
void func(void)
{
    処理
    if (条件) return;   // ⇒ 省略不可
	
    処理
    return;             // ⇒ 省略可
}

void

void func(void)
 1.    2.

  1. 値を返さない 返却値型に用いる
  2. 引数が無い場合に用いる

〇 演習問題

次のプログラムの水色部を別関数にしてプログラムを作成しなさい。

問1

#include <stdio.h>

int main(void)
{
    putchar('*');
    
    return 0;
}

問2

#include <stdio.h>

int main(void)
{
    char n = '*';
    
    putchar(n);
    
    return 0;
}

問3

#include <stdio.h>

int main( void )
{
    int a = 20;
    int b = 10;
    
    int c = a * b;
    printf("c = %d\n", c);
    
    return 0;
}

問4

#include <stdio.h>

int main( void )
{
    int a, b, c;
    
    puts("二つの整数値を入力 ");
    scanf("%d %d", &a, &b);
    
    if (a <= b) {
        c = a;
    }
    else {
        c = b;
    }
    
    printf("小さい方 = %d\n", c);
    
    return 0;
}

解答例

// 問1
#include <stdio.h>

void output_ast(void);

int main(void)
{
    output_ast();
    
    return 0;
}

/***
*を表示する関数
引数、返却値なし
***/
void output_ast(void)
{
    putchar('*');
}
// 問2
#include <stdio.h>

void output_char(char c);

int main(void)
{
    char n = '*';

    output_char(n);
    
    return 0;
}

/***
渡された文字を表示する関数
引数:char c;   // 表示する文字
返却値:なし
***/
void output_char(char c)
{
    putchar(c);

    return;
}
// 問3
#include <stdio.h>

int mul(int x, int y);

int main(void)
{
    int a = 20;
    int b = 10;

    int c = mul(a, b);
    printf("c = %d\n", c);

    return 0;
}

/***
乗算の結果を返す関数
引数:int x;   // 値1
      int y;   // 値2
返却値:乗算結果
***/
int mul(int x, int y)
{
    return x * y;
}
// 問4
#include <stdio.h>

int min(int x, int y);

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

    puts("二つの整数値を入力 ");
    scanf("%d %d", &a, &b);

    c = min(a, b);

    printf("小さい方 = %d\n", c);

    return 0;
}

/***
2値の小さい方を返す関数
引数:int x;    // 値1
      int y;    // 値2
返却値:小さい方の値
***/
int min(int x, int y)
{
    if (x <= y) {
        return x;
    }
    else {
        return y;
    }
}

● 補足:main関数

main関数もOS に対し戻り値を返却します。そのため、返却値型とreturn文を記述し、

int main(void)
{
    処理
    return 0;
}

とします。返却値の0は正常終了を示しています。異常時には0以外の値を返却します。

コメント