処理に名前をつけて再利用できる「関数」を学ぶ。
関数を使うとコードが整理され、同じ処理を何度でも呼び出せるようになる。
これまでのプログラムはすべて main() の中に書いてきた。
処理が増えると main がどんどん長くなり、読みにくくなる。
関数は「ひとまとまりの処理に名前をつけて、呼び出せるようにしたもの」。
| 要素 | 意味 | なくてもよいか |
|---|---|---|
| 引数(パラメータ) | 呼び出し元から受け取る値 | なくてもよい(void) |
| 戻り値(返却値) | 呼び出し元へ返す値 | なくてもよい(void) |
void 関数名(void) {
/* 処理 */
}
#include <stdio.h>
void hello(void)
{
printf("Hello, World!\n");
}
int main(void)
{
hello(); /* 関数を呼び出す */
hello(); /* 何度でも呼び出せる */
return 0;
}
Hello, World! Hello, World!
void 関数名(データ型 引数名) {
/* 処理 */
}
#include <stdio.h>
void printTimes(int times) /* times という名前で int を受け取る */
{
int i;
for (i = 0; i < times; i++) {
printf("こんにちは\n");
}
}
int main(void)
{
printTimes(3); /* 3 を渡す */
printTimes(1); /* 1 を渡す */
return 0;
}
こんにちは こんにちは こんにちは こんにちは
#include <stdio.h>
void printSum(int a, int b) /* 2つの引数を受け取る */
{
printf("%d + %d = %d\n", a, b, a + b);
}
int main(void)
{
printSum(10, 5);
printSum(3, 7);
return 0;
}
10 + 5 = 15 3 + 7 = 10
データ型 関数名(void) {
return 値;
}
#include <stdio.h>
int getFixed(void)
{
return 7 * 3; /* 計算結果を返す */
}
int main(void)
{
int result = getFixed();
printf("結果: %d\n", result);
return 0;
}
結果: 21
最もよく使う形。受け取った値を計算して返す。
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main(void)
{
int result = add(10, 15);
printf("合計: %d\n", result);
return 0;
}
合計: 25
#include <stdio.h>
double multiply(int x, double y)
{
return x * y;
}
int main(void)
{
double result = multiply(3, 2.5);
printf("積: %.2f\n", result);
return 0;
}
積: 7.50
| 引数 | 戻り値 | 定義の形 | 用途例 |
|---|---|---|---|
| なし | なし | void f(void) | メッセージ表示など |
| あり | なし | void f(int x) | 受け取った値を表示 |
| なし | あり | int f(void) | 固定値・設定値を返す |
| あり | あり | int f(int a, int b) | 計算・変換など |
整数を受け取り、絶対値を返す関数 absVal(int x) を作れ。
#include <stdio.h>
int absVal(int x)
{
/* ここを書く */
}
int main(void)
{
printf("%d\n", absVal(-5)); /* 5 */
printf("%d\n", absVal(3)); /* 3 */
printf("%d\n", absVal(0)); /* 0 */
return 0;
}
int absVal(int x)
{
if (x < 0) {
return -x;
}
return x;
}
2つの整数を受け取り、大きい方を返す関数 maxOf(int a, int b) を作れ。
#include <stdio.h>
int maxOf(int a, int b)
{
/* ここを書く */
}
int main(void)
{
printf("%d\n", maxOf(10, 5)); /* 10 */
printf("%d\n", maxOf(3, 8)); /* 8 */
printf("%d\n", maxOf(-2, -5)); /* -2 */
return 0;
}
int maxOf(int a, int b)
{
if (a >= b) {
return a;
}
return b;
}
配列と要素数を受け取り、合計と平均を表示する関数 printStats を作れ。
#include <stdio.h>
void printStats(int data[], int n)
{
/* ここを書く */
}
int main(void)
{
int scores[5] = {80, 70, 90, 60, 85};
printStats(scores, 5);
return 0;
}
void printStats(int data[], int n)
{
int i, sum = 0;
for (i = 0; i < n; i++) {
sum += data[i];
}
printf("合計: %d\n", sum);
printf("平均: %.1f\n", (double)sum / n);
}
Q1. 次のプログラムの出力として正しいものはどれか。
#include <stdio.h>
void printLine(void)
{
printf("AAAA");
}
int main(void)
{
printLine();
printLine();
return 0;
}
正解:イ
printLine() が2回呼ばれ、\n がないため「AAAA」が続けて出力される。
Q2. 次のプログラムの出力として正しいものはどれか。
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main(void)
{
printf("%d\n", add(3, add(4, 5)));
return 0;
}
正解:ウ(12)
内側の add(4, 5) = 9 が先に評価され、add(3, 9) = 12 になる。
Q3. 戻り値なし・引数なしの関数定義として正しいものはどれか。
正解:ウ
戻り値なしは void、引数なしも void と書く。順番は「戻り値の型 関数名(引数)」。
Q4. 関数を使う利点として正しいものはどれか。
正解:イ
再利用性・可読性・保守性の向上が関数の主な利点。修正が1か所で済む。