関数
関数(かんすう、function)とは、入力された値に対してある決まった内容の計算を行い、入力された値に応じた処理結果を返す、数式、あるいは命令の集まりのことです。
多くのプログラミング言語や処理系では、使用頻度の高い処理手続きは関数としてあらかじめ用意されており、C言語においても算術や文字列操作に関する関数が用意されています。
関数に入力する値は「引数(パラメータ)」と呼ばれ、関数内の処理で必要な情報を受け渡します。
使用頻度の高い一連の処理を関数として定義し、共通化することで、処理の煩雑化が抑止され、保守性が向上します。
また、処理の共通化により入力情報の異なる同じ処理を1か所にまとめることで記述するステップ数(ソースコードの行数:LOC、lines of code)が減少し、生産性が向上します。
関数の定義
関数は、入出力情報として「引数」を受け渡し、関数内での実行結果を「戻り値(または返り値)」として関数の呼び出し元に返すことができます。
この「引数」、及び「戻り値」は任意であり、これらを指定しない関数の定義も可能です。
構文
戻り値の型 関数名(引数1の型 引数1, 引数2の型 引数2, ...) { ... 関数内の処理 ... return 戻り値; }
関数の利用
定義した関数を利用する場合、関数の呼び出しは対象となる関数が既に定義されている必要があります。
その為、定義した関数の後に呼び出し元となる関数を記述する必要があります。
これはコンパイラが、ソースファイルの解析を上から順に行う為、関数の呼び出し元をコンパイルした時点で対象の関数が定義されていない場合、その関数の型を判断することが出来ないためです。
(この時点ではコンパイラは既定の型(戻り値:int型、引数:int型)で仮定し、コンパイルを続行しますが、該当関数の定義がこの仮定と異なる場合、エラーとしてコンパイルを中止します。)
但し、「プロトタイプ宣言」を行い、あらかじめ関数の型を定義しておくことでこの問題を回避することが可能です。
関数を使用した記述例(値渡し)
// 関数 program in C.
#include <stdio.h>
#define TAX 1.08F
// 税込金額計算
int TaxIncluded(int amount)
{
return amount * TAX;
}
int main(int argc, char *args[])
{
int amount = 200; // 金額
printf("税抜:%d,税込:%d\n", amount, TaxIncluded(amount));
return 0;
}
引数としてint型の金額を受け取り、戻り値として税込みの金額を返却する関数の実装例です。
実行結果
税抜:200,税込:216
関数を使用した記述例(ポインタ渡し)
// 関数 program in C.
#include <stdio.h>
#include <string.h>
// 空白をアンダースコアに置換
char *SpaceToUnderscore(char *str)
{
char *p;
while ((p = strchr(str, ' ')) != NULL) *p = '_';
return str;
}
int main(int argc, char *args[])
{
char str[] = {"sample program in C."};
printf("%s\n", SpaceToUnderscore(str));
return 0;
}
引数として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)
{
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);
}
int main(int argc, char *args[])
{
int amount = 200; // 金額
OutputLog("%s,val=%d", "message", amount);
return 0;
}
printf()と同じ引数を受け取り、現在時刻を付与した上でコマンドプロンプト上に文字列を出力する関数(戻り値なし)の実装例です。
現在日付は現在日付を「yyyy/mm/dd hh24:mi:ss」の形式で引数に返却する関数を定義しています。
実行結果
2017/06/28 11:30:53 message,val=200