閉じる

【C言語】関数の引数と戻り値についてわかりやすく解説

C言語でプログラムを書いていると、同じような処理を何度も書く場面が出てきます。

そのたびに同じコードをコピーしていると、ミスが増えたり、修正が大変になったりします。

そこで登場するのが関数です。

本記事では、関数の引数と戻り値に焦点を当てて、C言語初心者の方にも分かりやすいように、実際のサンプルコードを交えながら丁寧に解説していきます。

C言語の関数とは

関数の基本構造(戻り値 型名 関数名(引数)…)

C言語の関数は、特定の処理に名前を付けてまとめたものです。

最も基本的な書き方は次の形になります。

戻り値の型 関数名(引数の型 引数名, ...) という形式です。

関数の一般的な形

C言語
// 戻り値の型: int
// 関数名: add
// 引数: int a, int b
int add(int a, int b) {
    int result;         // 計算結果を保存する変数
    result = a + b;     // a と b を足し算
    return result;      // 計算結果を呼び出し元へ返す
}

この例では、戻り値の型としてintを指定しています。

つまりこの関数addは、int型の値を1つ返す関数です。

関数の基本構造を表に整理すると次のようになります。

部分役割
戻り値の型int関数が返す値の型を指定します
関数名add関数を呼び出すときに使う名前です
引数リストint a, int b関数に渡す値(入力)を定義します
関数本体{ ... }実際に処理を書きます

戻り値の型・関数名・引数・本体の4つを押さえておくと、関数の読み書きがしやすくなります。

main関数と自作関数の違い

C言語のプログラムは、必ずmain関数から実行が始まります

このmain関数も、他の関数と同じく「関数」の一種ですが、いくつか特徴があります。

main関数の特徴

C言語
#include <stdio.h>

int main(void) {
    // プログラムの最初に実行される場所
    printf("Hello, C language!\n");
    return 0;  // OS に終了コード0を返す(正常終了の意味)
}

main関数には、次のような特徴があります。

1つ目に、プログラムの入り口になる特別な関数であることです。

C言語の処理は必ずmainから始まり、mainが終わるとプログラム全体も終了します。

2つ目に、戻り値の型が通常intに決まっていることです。

return 0;のように整数を返すことで、プログラムの終了状態をOSに知らせます。

これに対して、自分で作る関数(自作関数)は次のような違いがあります。

  • 関数名は自由に決められる(addprint_messageなど)
  • 戻り値の型も自由に決められる(intdoublevoidなど)
  • プログラムの中で必要になったときにmainや他の関数から呼び出される

main関数は「入口」、自作関数は「部品」と考えると分かりやすいです。

関数を使うメリット

関数を使うと、プログラムの書き方や管理の仕方が大きく改善されます。

特に初心者のうちから意識しておきたいメリットは次の3つです。

1つ目は同じ処理を何度も書かなくてよくなることです。

足し算や平均値の計算、メッセージ表示などを関数にしておけば、必要なときに呼び出すだけで済みます。

2つ目はプログラムの見通しがよくなることです。

長いmainの中に全部の処理を書くと、後で読みにくくなりますが、処理ごとに関数に分けることで「何をしているか」がすぐに分かります。

3つ目はバグ修正や機能変更が簡単になることです。

例えば、平均値の計算方法を変えたくなった場合に、その関数だけ修正すれば、呼び出している場所は修正不要になります。

このように、関数はコードの再利用性・読みやすさ・保守性を高めるための重要な仕組みです。

C言語の引数とは

引数の役割

引数とは、関数に渡す入力データのことです。

関数はこの引数をもとに処理を行い、その結果を戻り値として返します。

例えば「2つの数の和を計算する関数」を考えるとき、足される数足す数を関数に渡す必要があります。

この2つが引数です。

C言語
int add(int a, int b) {
    return a + b;  // a と b は「引数」
}

この例ではabが引数であり、関数の中で自由に使える変数として扱われます。

「関数に必要な材料を渡す仕組み」が引数だとイメージするとよいです。

引数の宣言方法と型

引数を使うには、関数の宣言部分で「型」と「名前」をセットで書く必要があります。

単純な引数宣言の例

C言語
// 1つの int 型引数を受け取る関数
int square(int x) {
    return x * x;
}

// 1つの double 型引数を受け取る関数
double half(double value) {
    return value / 2.0;
}

引数の宣言では、次の2点が重要です。

1つ目に引数の型を指定することです。

intdoubleなど、通常の変数と同じように型を書きます。

2つ目に引数の名前を決めることです。

この名前は、関数の中でその値を参照するために使われます。

関数の外の変数名とは別物です。

例えばint xという引数宣言は、「整数型の入力データを1つ受け取り、そのデータを関数内ではxという名前で使う」という意味になります。

複数の引数と順番のルール

関数は、カンマで区切って複数の引数を定義できます。

ただし、引数の順番はとても重要です。

複数引数の例

C言語
// 2つの整数を受け取り、その差(a - b)を返す関数
int subtract(int a, int b) {
    return a - b;
}

int main(void) {
    int x = 10;
    int y = 3;
    int result1, result2;

    result1 = subtract(x, y);  // 10 - 3 = 7
    result2 = subtract(y, x);  // 3 - 10 = -7 (順番が逆なので結果も違う)

    return 0;
}

この例では、subtract関数の引数は(int a, int b)の順番で定義されています。

呼び出し時にsubtract(x, y)と書くとa = xb = yが対応します。

引数に関する重要なルールは次の通りです。

  • 引数は左から順に、呼び出し側の値が対応する
  • 型の数と順番も一致していなければならない
  • 引数の順番を間違えると、意図しない計算結果になる

初心者のうちは、「引数は位置で対応する」という点を意識して、名前だけで判断しないようにすることが大切です。

実引数と仮引数の違い

引数には、実引数仮引数という2つの用語があります。

意味の違いを理解しておくと、関数の動作がイメージしやすくなります。

用語の整理

用語読み方意味
仮引数かりひきすう関数定義側で書く引数(受け取る側)
実引数じつひきすう関数を呼び出すときに渡す値(渡す側)

サンプルで確認

C言語
#include <stdio.h>

// 仮引数: int a, int b
int add(int a, int b) {
    return a + b;
}

int main(void) {
    int x = 5;
    int y = 7;
    int ans;

    // 実引数: x, y
    ans = add(x, y);  // x の値が a に、y の値が b に渡される

    printf("答えは %d です\n", ans);
    return 0;
}

ここで、

  • int add(int a, int b)ab仮引数
  • add(x, y)xy実引数

です。

イメージとしては、実引数の「値」が仮引数にコピーされると考えると分かりやすいです。

引数なしの関数(void引数)の書き方

関数の中には、引数を必要としないものもあります。

例えば、「固定のメッセージを表示するだけ」の関数などです。

そのような場合は、引数リストにvoidと書きます。

引数なしの関数の例

C言語
#include <stdio.h>

// 引数なし、戻り値なしの関数
void print_hello(void) {
    printf("こんにちは、C言語の世界!\n");
}

int main(void) {
    print_hello();  // 引数は渡さない
    return 0;
}

ポイントは次の2つです。

1つ目に、関数定義側の引数リストにvoidと書くことです。

これは「何も受け取りません」という宣言になります。

2つ目に、呼び出し側ではprint_hello();のように何も渡さないことです。

カッコの中は空にしておきます。

このように、引数が不要な場合はvoidを使って明示的に「受け取らない」と書くのがC言語のスタイルです。

C言語の戻り値とは

戻り値の役割

戻り値とは、関数が処理した結果として、呼び出し元に返す値です。

例えば、足し算の結果や、平均値の計算結果などが戻り値になります。

C言語
int add(int a, int b) {
    int result = a + b;
    return result;  // これが戻り値
}

呼び出し側では、この戻り値を変数に代入したり、さらに別の計算に使えます。

C言語
int x = add(3, 4);  // add(3, 4) の戻り値 7 が x に入る

「関数の出力」が戻り値と考えるとよいです。

引数が入力、戻り値が出力という関係になります。

戻り値の型とreturn文の使い方

戻り値は、関数の宣言で指定した型と一致していなければなりません

また、戻り値を返すためにはreturn文を使います。

基本的なreturn文の例

C言語
// int 型を返す関数
int double_int(int x) {
    return x * 2;  // int 型の値を返す
}

// double 型を返す関数
double double_double(double x) {
    return x * 2.0;  // double 型の値を返す
}

ここで重要なのは、戻り値の「型」とreturnで返す式の「型」が一致していることです。

また、return文には2つの役割があります。

1つ目に値を呼び出し元に返すことです。

2つ目に関数の処理をその場で終了することです。

例えば次のようなコードでは、returnの後の行は実行されません。

C言語
int sample(int x) {
    return x + 1;
    // ここに何か書いても実行されない
}

戻り値あり関数と戻り値なし関数

C言語の関数には、戻り値がある関数戻り値がない関数の2種類があります。

戻り値あり(非void)の関数

C言語
int add(int a, int b) {
    return a + b;  // int の値を返す
}

戻り値ありの関数は、計算結果を使いたい場合に便利です。

例えば、結果を変数に入れて後で利用したり、別の関数に渡したりできます。

戻り値なし(void)の関数

C言語
#include <stdio.h>

// 戻り値なしの関数
void print_message(void) {
    printf("処理が完了しました。\n");
}

voidを戻り値の型に指定すると、「何も返さない」という意味になります。

そのため、この関数内でreturn;を書く場合は、値を指定せずにreturn;だけを書きます。

「何かを計算して結果が必要」なら戻り値あり、「画面表示だけする」なら戻り値なしというように、役割に応じて使い分けるとよいです。

1つしか返せない戻り値と設計の考え方

C言語の関数は、戻り値を1つしか返せません

例えば、「合計」と「平均」の2つを同時に返したい、といったことは直接はできません。

この制約を踏まえて、次のような設計の工夫が必要になります。

1つの方法は、本当に必要な結果だけを戻り値にするという考え方です。

例えば「計算が成功したかどうか」を戻り値として01で返すなどです。

もう1つの方法は、戻り値以外の手段で複数の値を扱うことです。

ポインタや配列を使って、複数の結果を関数の外側の変数に書き込む方法がありますが、これは少しレベルが上がるため、初心者のうちは「戻り値は1つだけ」と覚えておけば十分です。

設計のポイントとしては、「その関数は何をしたい関数なのか」を明確にし、最も重要な1つを戻り値にするという意識を持つことです。

サンプルコードで学ぶ引数と戻り値

ここからは、具体的なサンプルコードを通して、引数と戻り値の使い方を確認していきます。

足し算関数

まずはとてもシンプルな「2つの整数を足し算する関数」です。

C言語
#include <stdio.h>

// 2つの int 型の数値を受け取り、その和を返す関数
int add(int x, int y);  // 関数宣言(プロトタイプ宣言)

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

    // add 関数を呼び出し、戻り値を sum に代入
    sum = add(a, b);

    printf("a と b の合計は %d です。\n", sum);

    return 0;
}

// 関数定義
int add(int x, int y) {
    int result;

    // x と y を足し算
    result = x + y;

    // 足し算の結果を呼び出し元へ返す
    return result;
}
実行結果
a と b の合計は 30 です。

この例では、

  • 引数(int x, int y)が入力
  • resultreturn result;で戻り値として返す

という形で、引数と戻り値がセットで動いていることが確認できます。

平均値を計算する関数

次に、2つの整数の平均値をdouble型で返す関数を作成してみます。

ここでは、異なる型を組み合わせて使う点にも注目してみてください。

C言語
#include <stdio.h>

// 2つの int 型の数の平均を double 型で返す関数
double average(int a, int b);  // 関数宣言

int main(void) {
    int x = 5;
    int y = 8;
    double ave;

    ave = average(x, y);  // 戻り値を ave に代入

    printf("%d と %d の平均は %f です。\n", x, y, ave);

    return 0;
}

// 関数定義
double average(int a, int b) {
    double result;

    // (a + b) / 2 の結果を double 型として計算
    result = (a + b) / 2.0;

    return result;
}
実行結果
5 と 8 の平均は 6.500000 です。

ここでのポイントは、戻り値の型がdoubleであり、計算式の中でも2.0のように小数を使っていることです。

これにより、整数同士の割り算ではなく、小数を含む割り算になります。

「どの型で返したいか」を意識して、戻り値の型を決めることが重要です。

メッセージを表示する関数

次は、戻り値なし・引数ありの例として、メッセージを表示する関数を作ってみます。

C言語
#include <stdio.h>

// 名前を受け取り、あいさつメッセージを表示する関数
void greet(int hour);  // 関数宣言

int main(void) {
    greet(10);  // 10時としてあいさつ
    greet(18);  // 18時としてあいさつ

    return 0;
}

// 関数定義
void greet(int hour) {
    // hour の値によってあいさつを変える
    if (hour < 12) {
        printf("おはようございます。\n");
    } else if (hour < 18) {
        printf("こんにちは。\n");
    } else {
        printf("こんばんは。\n");
    }

    // 戻り値はないので return は省略してもよい
}

想定される実行結果の例は次のようになります。

実行結果
おはようございます。
こんにちは。

この関数greetは、引数hourをもとに表示内容を変えていますが、画面に表示するだけで戻り値は必要ないため、戻り値の型はvoidになっています。

判定結果を返す関数

次に、戻り値を使って「判定結果」を返す例として、整数が偶数か奇数かを判定する関数を作ります。

C言語
#include <stdio.h>

// 整数 n が偶数なら 1、奇数なら 0 を返す関数
int is_even(int n);  // 関数宣言

int main(void) {
    int value = 7;

    if (is_even(value)) {
        // is_even(value) が 1 のときに実行される
        printf("%d は偶数です。\n", value);
    } else {
        // is_even(value) が 0 のときに実行される
        printf("%d は奇数です。\n", value);
    }

    return 0;
}

// 関数定義
int is_even(int n) {
    if (n % 2 == 0) {
        return 1;  // 偶数の場合は 1 を返す
    } else {
        return 0;  // 奇数の場合は 0 を返す
    }
}
実行結果
7 は奇数です。

この例では、戻り値を「状態のフラグ」として使っている点がポイントです。

10で「はい・いいえ」を表現し、if文で分岐に利用しています。

このように、戻り値は「計算結果」だけでなく、処理が成功したかどうか・条件を満たしているかどうかなどの判定にもよく使われます。

関数宣言(プロトタイプ宣言)と定義・呼び出しの流れ

最後に、関数宣言(プロトタイプ宣言)と定義・呼び出しの関係を、簡単なサンプルで整理します。

C言語では、関数を呼び出す前に「このような関数がある」と知らせておく必要があります

これがプロトタイプ宣言です。

C言語
#include <stdio.h>

// プロトタイプ宣言: コンパイラに「こんな関数があります」と知らせる
int add(int a, int b);
void print_result(int value);

int main(void) {
    int x = 3;
    int y = 4;
    int sum;

    // 関数呼び出し
    sum = add(x, y);

    // 結果を表示する関数の呼び出し
    print_result(sum);

    return 0;
}

// 関数定義: 実際の処理の中身を書く部分

// 2つの整数の和を返す関数
int add(int a, int b) {
    return a + b;
}

// 結果を表示する関数(戻り値なし)
void print_result(int value) {
    printf("計算結果は %d です。\n", value);
}
実行結果
計算結果は 7 です。

ここで、関数の流れを整理してみます。

1つ目に、プロトタイプ宣言です。

int add(int a, int b); のように、;で終わる形で宣言だけを行います。

これにより、コンパイラは「addという関数があって、引数はintが2つ、戻り値はint」と理解します。

2つ目に、関数の呼び出しです。

sum = add(x, y);のように書くことで、add関数が実行され、戻り値がsumに代入されます。

3つ目に、関数定義です。

ファイルの後半にint add(int a, int b) { ... }のように、本体を書く部分があります。

ここで実際の計算処理を記述します。

このように、「宣言」→「呼び出し」→「定義」という3つの段階を意識しておくと、複数の関数を含む大きなプログラムでも整理しやすくなります。

まとめ

本記事では、C言語の関数の引数と戻り値について、基本構造から具体的なサンプルコードまで詳しく解説しました。

引数は関数への「入力」、戻り値は関数からの「出力」という役割を持ちます。

関数を使いこなすことで、処理を分割し、再利用性や読みやすさを高めることができます。

初心者の方は、まずは足し算・平均・判定などのシンプルな関数を自分で書き、引数と戻り値の流れを体で覚えていくと良いでしょう。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!