確認問題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 のようにキャストで明示するのが安全です。
この講座の理解を深めるおすすめ書籍
サイトで動きを理解し、書籍で演習量を補うと効果的です
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。
Amazonで見る※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。