標準ライブラリ関数
ANSI C標準ではランタイムライブラリを標準ライブラリとして定義している.
標準ライブラリ関数を使う上で注意すべき点を示す.
標準入出力
ライブラリ関数
- memmove
memmoveはソースとデスティネーションの引数がオーバラップしても動作が保証されるが,memcpyは保証されない.そのため,memcpyの方がmemmoveに比べて効率が良いが,引数がオーバラップする可能性がある場合はmemmoveを用いた方が安全である.
- qsort
qsortを使って文字列の配列(char型のポインタの配列)をソートする場合,比較関数への引数は汎用ポインタvoid * または char *でなければならないため,比較関数は以下のようにする必要がある.
int pstrcmp(p1, p2) /* compare strings through pointers */
char *p1, *p2; /* void * for ANSI C */
{
return strcmp(*(char **)p1, *(char **)p2);
}
構造体の配列をソートするような場合も同様である.
- 数値の文字列への変換
数値を文字列に変換するには,sprintfが利用できる.文字列を整数に変換するにはatoi関数がある.
- 日付,時刻の取得
日付,時刻を取得するには,time, ctimeまたはlocaltime関数を用いる.
例を以下に示す.
#include <stdio.h>
#include <time.h>
main()
{
time_t now;
time(&now);
printf("It's %.24s.\n", ctime(&now));
exit(0);
}
timeは現在のtime_t型のカレンダ時間を返す.
localtimeはtime_t型のカレンダ時間を構造体tm型のローカル時間に変換する.
また,ctimeはカレンダ時間を印字可能なローカル時間の文字列に変換する.
逆に,mktimeは構造体tmのローカル時間をtime_t型のカレンダ時間に変換する.
- 乱数
乱数を生成するにはint rand(void)関数(0からRAND_MAXの間の疑似乱数整数を返す)を用いる.
疑似乱数の新しい系列の種を与えるためにはvoid srand(unsigned int)が使われる.乱数の種としては,時刻やユーザがキー入力を行なうまでの経過時間などが用いられる.
乱数として2進数0, 1が必要な場合に rand() % 2 を用いると乱数性に欠けることがある.これは疑似乱数生成において,下位ビットの乱数性が悪いためであり,このような場合は上位ビットを用いるようにする.
- 関数形式
以下の関数は古い形式のものであり,移植する場合などは対応するANSIの標準ライブラリ関数に置き換える.
旧関数 : ANSI関数
index : strchr
rindex : strrchr
bcopy : memmove(第1引数と第2引数を入れ換える)
bcmp : memcmp
bzero : memset(第2引数を0とする)
- ディレクトリの読み込み
多くのUNIXシステムではopendir(), readdir()が利用できる.また,Windowsではfindfirst(), findnext()が利用できる.
可変長引数
- 可変長引数リストマクロ
可変長引数リストマクロvar_startの形式は,ANSI CとUNIX System Vでは異なっている.また,UNIX System Vではva_alistおよびva_dclが使われている.そのため,UNIX System Vの可変長引数マクロを使ったプログラムをANSI Cで使う場合は変更が必要である.
- vprintf, vfprintf, vsprintf
vprintf, vfprintfおよびvsprintfは,対応するprintfと同様であるが,可変な引数リストがva_listで初期化される引数で置き換えられる点が異なる.
vprintfの使用例を以下に示す.
#include <stdio.h>
#include <stdarg.h>
void error(char *fmt, ...)
{
va_list argp;
fprintf(stderr, "error: ");
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
fprintf(stderr, "\n");
}
- 引数の個数
可変個の引数を取る関数において,関数が呼び出されたときの実際の引数の数を知る情報はない.可変個の引数を取る関数は,自身の引数を順次調べて引数の数を求める必要がある.
printfのような関数では,フォーマット文字列内の書式指定子の数を調べて引数の数を求めている.他の一般的な方法は,引数リストの最後に0, -1 あるいはnullポインタのような特別な値を用いることにより引数の終端を知る方法である.これは引数の型が全て同じときに有効である.
- 可変個引数関数
可変個の引数を取りかつ他の関数に可変個の引数を渡す関数を一般的に書くことはできない.