プロトタイプ宣言
プロトタイプ宣言(関数プロトタイプ、Function prototype)とは、C言語やC++における関数の宣言であり、関数本体の関数名、引数、戻り値のデータ型をあらかじめ宣言するものです。
コンパイラはソースファイルの解析を上から順に行う為、関数の呼び出し元をコンパイルした時点で対象の関数が定義されていない場合、その関数の型を判断することが出来ないためコンパイルエラーとなります。
(この時点ではコンパイラは既定の型(戻り値:int型、引数:int型)で仮定し、コンパイルを続行しますが、該当関数の定義がこの仮定と異なる場合、エラーとしてコンパイルを中止します。)
関数プロトタイプを宣言することで、関数を定義する位置を気にすることなくコーディングを行うことが可能となります。
また、ソースファイルを分割してプログラムを作成する場合に、関数プロトタイプを1か所で宣言することにより、プログラム内で使用される関数を一覧で確認することが可能となり、ソースコードの可読性が向上します。
プロトタイプ宣言の利用
関数プロトタイプは、実装する関数の「関数名」及び、「引数」の型、「戻り値」の型を宣言します。
引数の型を指定する際に引数の変数名は不要ですが定義することも可能です。
但し、関数利用時に変数名を強制されるわけではなく、Visual Studio等で該当関数の定義が表示された際に既定の変数名として表示されます。
構文
戻り値の型 関数名(引数1の型, 引数2の型, ...);
プロトタイプ宣言を使用した記述例(値渡し)
// プロトタイプ宣言 program in C.
#include <stdio.h>
#define TAX 1.08F
int TaxIncluded(int);
int main(int argc, char *args[])
{
int amount = 200; // 金額
printf("税抜:%d,税込:%d\n", amount, TaxIncluded(amount));
return 0;
}
// 税込金額計算
int TaxIncluded(int amount)
{
return amount * TAX;
}
引数としてint型の金額を受け取り、戻り値として税込みの金額を返却する関数の実装例です。
実行結果
税抜:200,税込:216
プロトタイプ宣言を使用した記述例(ポインタ渡し)
// プロトタイプ宣言 program in C.
#include <stdio.h>
#include <string.h>
char *SpaceToUnderscore(char*);
int main(int argc, char *args[])
{
char str[] = {"sample program in C."};
printf("%s\n", SpaceToUnderscore(str));
return 0;
}
// 空白をアンダースコアに置換
char *SpaceToUnderscore(char *str)
{
char *p;
while ((p = strchr(str, ' ')) != NULL) *p = '_';
return str;
}
引数としてchar型のポインタを受け取り、半角空白(0x20)をアンダースコア(0x5f)に置換し、戻り値として置換結果のchar型ポインタ(引数と同じ)を返却する関数の実装例です。
実行結果
sample_program_in_C.
プロトタイプ宣言を使用した記述例(戻り値なし)
// プロトタイプ宣言 program in C.
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
#define LOG_LINE_SIZE 256
#define DATE_SIZE 20
void Now(char *now);
void OutputLog(char *format, ...);
int main(int argc, char *args[])
{
int amount = 200; // 金額
OutputLog("%s,val=%d", "message", amount);
return 0;
}
void Now(char *now)
{
time_t timer = time(NULL);
struct tm *local = localtime(&timer);
snprintf(now, DATE_SIZE,
"%04d/%02d/%02d %02d:%02d:%02d",
local->tm_year + 1900, local->tm_mon + 1, local->tm_mday,
local->tm_hour, local->tm_min, local->tm_sec);
}
void OutputLog(char *format, ...)
{
va_list ap;
char line[LOG_LINE_SIZE] = { '\0' };
char now[DATE_SIZE] = { '\0' };
Now(now);
va_start(ap, format);
vsnprintf(line, sizeof(line), format, ap);
va_end(ap);
printf("%s\t%s\n", now, line);
}
printf()と同じ引数を受け取り、現在時刻を付与した上でコマンドプロンプト上に文字列を出力する関数(戻り値なし)の実装例です。
現在日付は現在日付を「yyyy/mm/dd hh24:mi:ss」の形式で引数に返却する関数を定義しています。
実行結果
2017/06/28 11:30:53 message,val=200