🇯🇵 日本語 | 🇺🇸 English

第31回 確認問題(関数)

戻り値、値渡し、void関数、プロトタイプ宣言の理解度を確認しましょう。

確認問題1 ― 戻り値の型

int add(int a, int b) {
    return a + b;
}
int main(void) {
    printf("%d\n", add(3, 7));
    return 0;
}

出力結果は?

7
10
3
コンパイルエラー
解説: add(3, 7) は a=3, b=7 を受け取り、3 + 7 = 10 を返します。

確認問題2 ― 値渡し

void change(int x) {
    x = 100;
}
int main(void) {
    int a = 5;
    change(a);
    printf("a = %d\n", a);
    return 0;
}

出力結果は?

a = 100
a = 5
a = 0
コンパイルエラー
解説: Cは値渡し。change の中の x は a のコピーです。
x を変更しても元の a には影響しません。a は 5 のままです。

確認問題3 ― void関数

void greet(void) {
    printf("Hello!\n");
    return 1;
}

このコードはどうなる?

正常にコンパイルされる
コンパイルエラー(または警告)
実行時エラー
Hello!と1が表示される
解説: void 関数は値を返せません。return 1;コンパイルエラーになります。
void関数からの return は return;(値なし)のみ許可されます。

確認問題4 ― 宣言と呼び出し順

#include <stdio.h>

int main(void) {
    printf("%d\n", square(5));
    return 0;
}

int square(int n) {
    return n * n;
}

このコードはどうなる?

25
コンパイルエラー(暗黙の宣言)
0
5
解説: square 関数が main より後に定義されています。
プロトタイプ宣言がないと、コンパイラは square を知らない状態で呼び出すため、暗黙の宣言警告やエラーになります。
解決策:main の前に int square(int n); と宣言するか、関数を main より前に置く。

確認問題5 ― ローカル変数のスコープ

void foo(void) {
    int x = 10;
}
int main(void) {
    foo();
    printf("%d\n", x);
    return 0;
}

このコードはどうなる?

10 と表示される
コンパイルエラー(xはスコープ外)
0 と表示される
実行時エラー
解説: ローカル変数のスコープは宣言されたブロック内のみ
  • foo 内で宣言された x は foo の中だけで有効
  • foo を抜けた時点で x は存在しなくなる
  • main の中から x は見えないので、「宣言されていない」というコンパイルエラー
関数間で値を受け渡すには、引数戻り値、またはグローバル変数を使います。

確認問題6 ― 関数の再帰呼び出し

int fact(int n) {
    if (n <= 1) return 1;
    return n * fact(n - 1);
}
int main(void) {
    printf("%d\n", fact(4));
    return 0;
}

出力結果は?

16
24
4
無限ループ
解説: 階乗(factorial)を計算する典型的な再帰関数
  • fact(4) = 4 * fact(3)
  • fact(3) = 3 * fact(2)
  • fact(2) = 2 * fact(1)
  • fact(1) = 1(ベースケース)
  • 結果: 4 * 3 * 2 * 1 = 24
再帰には必ず終了条件(ベースケース)が必要です。無いとスタックオーバーフローで停止します。

確認問題7 ― 複数の引数と順番

int sub(int a, int b) {
    return a - b;
}
int main(void) {
    printf("%d\n", sub(3, 10));
    return 0;
}

出力結果は?

7
-7
13
コンパイルエラー
解説: 引数は宣言した順番にマッピングされます。
  • 呼び出し: sub(3, 10)
  • 関数側: a=3, b=10
  • a - b = 3 - 10 = -7
引数の順序を間違えるとバグの原因になります。関数の意味を考えて順序を決めましょう。

確認問題8 ― 早期returnの動作

int check(int n) {
    if (n < 0) return -1;
    if (n == 0) return 0;
    return 1;
}
int main(void) {
    printf("%d\n", check(-5));
    return 0;
}

出力結果は?

0
-1
1
-5
解説: return 文が実行されると、そこで即座に関数から抜けます。
  • n = -5 なので n < 0 が真
  • return -1; が実行される
  • それ以降のコードは実行されない
この「早期 return」は、エラーチェックや境界条件の処理で多用されます。ネストを浅く保てる利点があります。

確認問題9 ― 引数の型変換

int twice(int x) {
    return x * 2;
}
int main(void) {
    double d = 3.7;
    printf("%d\n", twice(d));
    return 0;
}

出力結果は?

7.4
6
コンパイルエラー
8
解説: 関数の仮引数が int なので、double の値はint に暗黙変換(切り捨て)されます。
  • d = 3.7 → int に変換 → 3(小数部分は切り捨て、四捨五入ではない)
  • twice(3) = 3 * 2 = 6
型変換はコンパイラが警告を出すこともあります。意図的な変換は (int)d のようにキャストで明示するのが安全です。

結果

回答してください
関数の講座に戻るホームへ
← 前の講座
第30回 配列を引数に
次の講座 →
第32回 再帰関数

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で演習問題も充実。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ