今回は戻り値と引数の組み合わせについて説明します。
戻り値と引数の組み合わせとは、関数を作る場合に以下の組み合わせが考えられるということです。
戻り値 | 引数 |
---|---|
なし | なし |
あり | なし |
なし | あり |
あり | あり |
自分が作る関数がどれに当たるのか考えてから作る必要があります。
参考までに、これまで使ってきた「標準関数」を元に確認してみましょう。
<戻り値 なし 引数 なし のケース>
残念ながら、これまで使った「標準関数」に該当するものはありませんでした。
前回の「Greet関数」や「Animal関数」が該当しますね。
<戻り値 あり 引数 なし のケース>
これは、乱数の時に使ったrand関数が該当します。
サイコロを作る時など、
dice = rand() % 6 + 1; |
というプログラムを打ちますが、引数は無いため括弧内は何も書きませんし、戻り値は変数diceで受け取っています。
<戻り値 なし 引数 あり のケース>
これも、乱数の時に使ったsrand関数が該当します。
乱数の初期化は、
srand((unsigned int)time(NULL)); |
と書きました。
戻り値は無いため、受け取れません。
<戻り値 あり 引数 あり のケース>
標準関数では多いタイプですが、文字列の時に使ったstrlen関数などが該当します。
文字列の長さ(文字数)を調べる際に、
int length; length = strlen(str); |
などと書きました。
strというchar型配列が引数で、文字の長さが戻り値です。
よく使っているprintf関数は、戻り値を受け取ったことはありません。
では、戻り値は「なし」かというとそうでもないのです。
次のプログラムを動かしてみてください。
<sample program 127-01>
#include <stdio.h> int main(void) { int result; result = printf("Hello\n"); printf("result = %d\n", result); return 0; } |
<実行結果>
Hello result = 6 続行するには何かキーを押してください・・・
戻り値を受け取り、表示してみると「6」が入っていました。
実はprintf関数は「表示した文字数」を戻していたのです。
※改行文字も含めて6文字表示しています。
戻ってきた値を受け取るかどうかはユーザ次第ということです。
では、実際にこの4パターンの関数を作ってみましょう。
戻り値も引数も「なし」ケースは前回作ったので残りは3種類です。
まず、戻り値だけ「あり」のケースですが、サイコロの機能を持ったDice関数を作ろうと思います。
この関数を呼び出す度に1から6までのどれかの数値が戻されるというものです。
まずプロトタイプ宣言ですが、戻り値は整数ですのでint型で設定します。
int Dice(void); |
これでよさそうです。
本体の枠組みは、
int Dice(void) { } |
ですね。
プロトタイプ宣言の「;」以外をコピーして作れば簡単です。
問題は中身です。
値を戻すためにはreturn文を使います。
main関数でもreturn文が使われています。
int main(void) { return 0; } |
これは正常に終了した場合、「0」を戻すということです。
ファイルの所では、異常終了で「1」を戻すということも書きました。
int型の値であれば何でも戻すことが出来ます。
※main関数がどこに値を戻すか、については今は考えないでおきましょう。
乱数の1から6までを戻すのであれば、
return rand() % 6 + 1; |
と書けば良いのです。
<sample program 127-02>
#include <stdio.h> #include <stdlib.h> #include <time.h> int Dice(void); int main(void) { int number; int i; srand((unsigned int)time(NULL)); for (i = 0; i < 5; i++) { number = Dice(); printf("%d\n", number); } return 0; } int Dice(void) { return rand() % 6 + 1; } |
<実行結果>
1 2 5 4 4 続行するには何かキーを押してください・・・
関数の中身は1行だけですが、
number = rand() % 6 + 1; |
と書くよりも、
number = Dice(); |
と書いた方が、サイコロの目を受け取っているということが分かりやすいです。
これが、関数の利点の一つ「機能に名前を付ける」です。
その機能を「式」で見るより、「名前」で見た方が認識しやすいです。
2.戻り値「なし」 引数「あり」
さて、次は引数だけ「あり」のケースを考えましょう。
簡単に、渡された整数を16進数で表示するHexadecimal関数を作ります。
プロトタイプ宣言は、
void Hexadecimal(int value); |
としましょう。
引数として何かを受け取るためには、受け取るための変数が必要です。
今回は整数を受け取るので、int型の変数valueを用意しました。
続いて、本体の枠組みを作ります。
void Hexadecimal(int value) { } |
中身は単純にprintf関数で終わりそうです。
<sample program 127-03>
#include <stdio.h> void Hexadecimal(int value); int main(void) { Hexadecimal(1234); /*10進数を渡す */ Hexadecimal(0123); /* 8進数を渡す */ Hexadecimal(0x33); /*16進数を渡す */ return 0; } void Hexadecimal(int value) { printf("%X\n", value); } |
<実行結果>
4D2 53 33 続行するには何かキーを押してください・・・
Hexadecimal関数が受け取った引数は、変数valueに格納されます。
今回はvalueの中身を16進数で表示しただけですが、計算などに使っても良いのです。
3.戻り値「あり」 引数「あり」
3つ目のケースです。
渡した整数を2倍にして戻すTwice関数を作りましょう。
プロトタイプ宣言は、
int Twice(int value); |
にします。
本体の枠組みは
int Twice(int value) { } |
です。
中身も、受け取った値を2倍して戻すだけですので、難しくありません。
<sample program 127-04>
#include <stdio.h> int Twice(int value); int main(void) { int result; int a; result = Twice(13); printf("result = %d\n", result); a = 26; result = Twice(a); printf("result = %d\n", result); return 0; } int Twice(int value) { return value * 2; } |
<実行結果>
result = 26 result = 52 続行するには何かキーを押してください・・・
関数に引数を渡す際に、直接数値を渡しても良いですし、変数に入った数値を渡しても良いです。
上のプログラムでは、最初は「13」を2回目は変数「a」に入っている「26」を渡しています。
4.引数が複数あるケース
最後に引数が複数あるケースを考えます。
2つの整数を渡して、合計を戻すAdd関数を作りましょう。
2つ以上の引数がある場合は「,(コンマ)」で区切って書きますので、プロトタイプ宣言は、
int Add(int lhs, int rhs); |
となります。
lhsは「left-hand side」の略で「左辺」、rhsは「right-hand side」の略で「右辺」という意味です。
本体の枠組みは、
int Add(int lhs, int rhs) { } |
です。
中身は簡単なので、さらっと書きます。
<sample program 127-05>
#include <stdio.h> int Add(int lhs, int rhs); int main(void) { int result; int a; result = Add(2, 6); printf("result = %d\n", result); a = 5; result = Add(a, 8); printf("result = %d\n", result); return 0; } int Add(int lhs, int rhs) { return lhs + rhs; } |
<実行結果>
result = 8 result = 13 続行するには何かキーを押してください・・・
戻り値と引数の組み合わせの様々なケースを書きました。
まだ関数の基礎レベルですが、徐々に慣れていきましょう。