【基礎から学ぶプログラミング言語】 C言語/ユーザー定義関数のプロトタイプ宣言とユーザー定義関数の作成例

IT
スポンサーリンク
スポンサーリンク
スポンサーリンク

私たちは日常生活で何気なくパソコンやスマートフォンというコンピュータを使用しています。
これらのコンピュータが普通に動作しているのは、そのようにプログラミング言語が記述されているからです。
本記事は、そんなプログラミング言語について実際に学びながら要点をまとめていったメモという位置付けになります。
私は専攻が電気でプログラムに関しては全くの初心者ですので、同様に初心者の方には理解しやすくなっているかと思います。

今回は、「C言語/ユーザー定義関数のプロトタイプ宣言とユーザー定義関数の作成例」についての説明です。

1.初めに

前回は、ユーザー定義関数の作り方について説明しました。

今回は、プログラムが複雑になってくると必須になるプロトタイプ宣言と、ちょっと応用したユーザー定義関数の作成例をいくつか紹介していこうと思います。

2.関数のプロトタイプ宣言

通常、mainの中でユーザー定義関数を使用する場合、mainの前にユーザー定義関数を記述して使える状態にしておく必要があります。

なのですが、プログラムが複雑になってユーザー定義関数の数も増えてくると、冒頭にユーザー定義関数がいくつも並んで、肝心のmain部分が下の方に追いやられてしまいます。
そういう管理方法が良い場合もあるかもしれませんが、見づらいと感じることもあるでしょう。
その為、ユーザー定義関数は任意の位置に配置できた方が便利だと思いませんか?

そこで登場するのがプロトタイプ宣言です。

名称が仰々しいですが内容は何も難しくないので、早速見ていきましょう。

#include<stdio.h>

double ave(double, double);

void main() {
double a, b, c = 2.0;
a = ave(1.1, 8.9);
b = ave(a, c);
printf(“a = %f\n”, a);
printf(“b = %f\n”, b);
}

double ave(double x, double y) {
double z = (x + y) / 2.0;
return z;
}

図1 右は比較用のプロトタイプ宣言未使用の場合

このプログラムは、図1右のプログラムと全く同じ動きをします。
図1右のプログラムは前回説明したものなので、動きが理解できない場合は前回の記事を見直してください。

何やら冒頭にどんな内容なのか記述されていないユーザー定義関数がありますよね?
これがプロトタイプ宣言です。
このように記述することで、『これからaveというユーザー定義関数を使用しますよ!』と宣言されるわけです。
こうしてプロトタイプ宣言をしたら、実際のユーザー定義関数の記述は好きな位置に移動させても問題無くなります。

ただ、プロトタイプ宣言を見てみると、変数名は消えていますが、引数部分にどんな変数が入ってくるのか示すdoubleだけは残っていますよね?
プロトタイプ宣言をする際は、このように引数の形態だけは指定しておく必要がありますので注意しましょう

また、プロトタイプ宣言の場合はこっそりと「;」がくっついていますので、ここも注意です。

ちなみに、プロトタイプ[prototype]は[原型・試作品]という意味なので、何となくその効果をイメージできます。

3.ユーザー定義関数の使用例

プロトタイプ宣言について理解できたと思いますので、ユーザー定義関数を使った他の例をいくつか見てみましょう。

2つの整数の内、大きい数値を求める

#include<stdio.h>

int max(int, int);

void main() {
int a, b;
printf(“整数aを入力してください。”);
scanf(“%d”, &a);
printf(“整数bを入力してください。”);
scanf(“%d”, &b);
printf(“入力した2値の内、大きい整数は%dです。”, max(a, b));
}

int max(int x, int y) {
if (x > y) {
return x;
}
return y;
}

図2

このプログラムでは、整数を2種類入力すると、大きい方の整数を表示することが可能です。
実行すると、以下のように動作します。

図3

ここで定義したユーザー定義関数は16~22行目に記述した【max】です。
4行目でプロトタイプ宣言をしているので、本体は下に書いてあっても良いのです。

では、【max】というユーザー定義関数の中身を確認してみましょう。

まず、16行目で整数の変数maxを定義しています。
引数は整数xと整数yですね。

そして、この引数を18行目のif文で条件分岐させています。
【x > y】なので、整数xが整数yより大きい場合は19行目(戻り値が整数xになる)、この条件を満たさない場合は20行目(戻り値が整数yになる)が実行されます
つまり、整数xと整数yの2値の内、大きい方の数値が整数maxになることがわかります。
その為、【max(a,b)】とすれば、aとbの内大きい数値が求められる関数が出来上がります。

後は、6~13行目のプログラムで整数a及び整数bをキーボードで入力するように促し、その入力値から大きい値は何だったのかが出力されるように指定してあるわけです。
maxは整数なので、printfの変換指定子%dで読み出せるんですよ。

特定の文字列を出力する(voidの意味)

上記で動作を説明したプログラムの出力結果の見た目が寂しいので、以下のようにしてみました。

図4

やり方は簡単で、printfで「-(ハイフン)」を複数出力するようにするだけです。
この表示もユーザー定義関数で実現してしまいましょう。

#include<stdio.h>

int max(int, int);
void line();

void main() {
int a, b;
line();
printf(“整数aを入力してください。”);
scanf(“%d”, &a);
printf(“整数bを入力してください。”);
scanf(“%d”, &b);
printf(“入力した2値の内、大きい整数は%dです。”, max(a, b));
line();
}

void line() {
printf(“————————————\n”);
}

int max(int x, int y) {
if (x > y) {
return x;
}
return y;
}

図5 ※下の方は見切れていますが、maxの記述があります。

追加されたのは、5・9・15・18~21行目です。
これで実行すると、図4のように表示されるようになります。

この時点で見た目が結構ゴチャゴチャしてきたので、プロトタイプ宣言の有難味がわかってきます。
プロトタイプ宣言をしていなければ、18~29行目が冒頭に来てしまいますからね…。

18~21行目を見てみると、【void line()】という記述があります。
これまで何となく【void main()】と記述してきた【void】が単品で出てきましたね。
ここに来てやっとコイツが何者なのかの説明に移れます。

【void】は、論理値を戻さないという宣言です。

ユーザー定義関数は、引数を用意して、戻り値を設定して作るものだと説明しました。
なのですが、ユーザー定義関数の中には、今回の例のようにprintfを使って文字を表示するだけのような何らかの計算をして戻り値を返す必要が無いものも存在します。
このようなユーザー定義関数を定義する場合は戻り値は不要なので、【void】がくっつくのです。

ただ、この関係はユーザー定義関数に留まりません。
【void】は【main】にもくっついているでしょう?
【main】は、中括弧内のプログラムを実行するだけで値を返すわけではないので【void】が付くんですね。

ここで新たに設定したいユーザー定義関数は、printfで「-(ハイフン)」を複数出力するだけです。
つまり、戻り値はありませんので、voidがくっつきます。
そして、引数も存在しませんので、プロトタイプ宣言が【void line();】という具合に括弧内の表示も無くなります。
これまで出てきたユーザー定義関数は全て引数があったから(a,b)とか記述していたのであって、引数が無いのなら括弧内は空白になるんです。

また、戻り値が無いので、【return;】と記述する必要も無くなっています。
本来なら21行目に【return;】と付きますが、無くなっているでしょう?
まあ、書いても普通に動作するんですけどね。

後は、【line();】という記述をすれば、そこには自動的に「-(ハイフン)」が複数出力されるようになるというわけです。

ちなみに、printf内で%dや%fの変換指定子を使って数値を呼び出す場合、【void line(int);】・【void line(int , int);】のようなプロトタイプ宣言になります。

void kazu(int);

kazu(a);
kazu(b);

void kazu(int z) {
printf(“入力:%d\n”,z);
return;
}

上記の記述を所定の箇所に追加することで、図6のような結果を得ることができます。

図6

どこに挿入すれば良いのかは試しに考えてみてくださいな。

void kazu(int);
・プロトタイプ宣言なので、6行目辺りに追加。

kazu(a);
kazu(b);
・13行目と14行目の間に追加。

void kazu(int z) {
printf(“入力:%d\n”,z);
return;
}
・ユーザー定義関数の中身なので、【main】の中でなければどこに記述してもOK。
・先述の通り、【return:】は無くても構いません。

以上、C言語/ユーザー定義関数のプロトタイプ宣言とユーザー定義関数の作成例についての説明でした。