1. 関数からデータを返す
第11章の1 で見てきたように、下位の関数(呼ばれる側)から上位の関数(呼ぶ側)へデータを返すことができますが、 それには、「1個の戻り値を返す方法」と、「複数の戻り値を返す方法」があります。
2. 1個の戻り値を返す
1個の戻り値を返す場合には、第11章の1 のように、
return 戻り値;
で値を返します。
3. 複数の戻り値を返す
複数の戻り値を返す方法には、「配列のアドレスを引数にする方法」と、 「複数の変数のアドレスを引数にする方法」があります。
(1) 配列を使って複数の戻り値を返す
配列の先頭要素のアドレスを引数にして、上位関数側と下位関数側で配列を共有し、見かけ上、複数のデータを返したようにします。
#include <stdio.h>
#define N 7 // 配列要素数
void waru2(int *p, int n);
int main(void)
{
int i;
int dt[N] = {20, 10, 4, 35, 66, 78, 2};
waru2(dt, N); // 配列の先頭要素のアドレスと要素数を渡す
for(i = 0; i < N; i++) {
printf("%d ", dt[i]);
}
printf("\n");
return 0;
}
/***
配列要素を2で割る関数
引数:int *p; 配列の先頭要素へのポインタ
int n; 配列要素数
***/
void waru2(int *p, int n) // 配列dt のアドレスをポインタp に入れる
{
for (int i = 0; i < n; i++) {
*(p + i) /= 2; // ポインタの指す値を 2 で割る
}
}
【実行結果例】
10 5 2 17 33 39 1

(2) 変数を使って複数の戻り値を返す
複数の変数のアドレスを引数にして、上位関数側と下位関数側でデータを共有し、見かけ上、複数のデータを返したようにします。
#include <stdio.h>
#define N 8
void max_min(int p[], int n, int *mx, int *mn);
int main(void)
{
int array[N] =
{45, 78, 345, 987, 23, 2, 92, 123};
int max, min;
max_min(array, N, &max, &min);
printf("最大値 = %d\n", max);
printf("最小値 = %d\n", min);
return 0;
}
/***
配列要素の最大値と最小値を返す関数
引数:int p[]; 配列の先頭要素へのポインタ
int n; 配列の要素数
int *mx; 最大値を格納する変数へのポインタ
int *mn; 最小値を格納する変数へのポインタ
***/
void max_min(int p[], int n, int *mx, int *mn)
{
*mx = *mn = p[0]; // 初期値は配列の先頭
for (int i = 1; i < n; i++) {
// より大きな値があったらmaxを入れ替え
if (*mx < p[i]) {
*mx = p[i];
}
// より小さな値があったらminを入れ替え
if (*mn > p[i]) {
*mn = p[i];
}
}
}
【実行結果例】
最大値 = 987
最小値 = 2

〇 演習問題
キーボードから入力した2つの整数値の和差積商を求めるプログラムを作りたい。
和差積商を求める部分は関数にすることとする。
次の仕様に従った関数を作成し、2つのプログラムを作りなさい。
問1
関数名称: keisan1
引数: int x; 計算に使う整数値1
int y; 計算に使う整数値2
int *wa; 和を入れる変数のポインタ
int *sa; 差を入れる変数のポインタ
int *seki; 積を入れる変数のポインタ
double *shou; 商を入れる変数のポインタ
戻り値: 無し
【実行結果例】
整数値を2つ入力しなさい 20 6
和 = 26 差 = 14 積 = 120 商 = 3.333333
問2
関数名称: keisan2
引数: int x; 計算に使う整数値
int y; 計算に使う整数値
int *p; 和差積商を入れる配列のポインタ
(上から順に和差積商を格納する)
戻り値: 無し
【実行結果例】
整数値を2つ入力しなさい 20 6
和 = 26 差 = 14 積 = 120 商 = 3
解答例
// 問1
#include <stdio.h>
void keisan1(int x, int y, int *wa, int *sa, int *seki, double *shou);
int main(void)
{
int dt1, dt2;
int sum, diff, mul;
double div;
printf("整数値を2つ入力しなさい ");
scanf("%d %d", &dt1, &dt2);
keisan1(dt1, dt2, &sum, &diff, &mul, &div); // 和差積商を求める
printf("和 = %d 差 = %d 積 = %d 商 = %f\n", sum, diff, mul, div);
return 0;
}
/***
和差積商を求める関数
引数:int x; 計算に使う整数値1
int y; 計算に使う整数値2
int *wa; 和を入れる変数のポインタ
int *sa; 差を入れる変数のポインタ
int *seki; 積を入れる変数のポインタ
double *shou; 商を入れる変数のポインタ
返却値:なし
***/
void keisan1(int x, int y, int *wa, int *sa, int *seki, double *shou)
{
*wa = x + y;
*sa = x - y;
*seki = x * y;
if (y != 0)
*shou = (double)x / y;
else
printf("エラー:0で割り算はできません\n");
}
// 問2
#include <stdio.h>
void keisan2(int x, int y, int *p);
int main(void)
{
int dt1, dt2;
int answer[4];
printf("整数値を2つ入力しなさい ");
scanf("%d %d", &dt1, &dt2);
keisan2(dt1, dt2, answer); // 和差積商を求める
printf("和 = %d 差 = %d 積 = %d 商 = %d\n",
answer[0], answer[1], answer[2], answer[3]);
return 0;
}
/***
和差積商を求める関数
引数:int x; 計算に使う整数値1
int y; 計算に使う整数値2
int *p; 和差積商を入れる配列のポインタ
(上から順に和差積商を格納する)
返却値:なし
***/
void keisan2(int x, int y, int *p)
{
*p = x + y;
*(p + 1) = x - y;
*(p + 2) = x * y;
if (y != 0)
*(p + 3) = x / y;
else
printf("エラー:0で割り算はできません\n");
}
コメント