C言語の基本|C言語の標準ライブラリ関数の基本

よく使う処理は、信頼できる関数に任せよう。標準ライブラリを知れば、C言語のプログラムはもっと短く、読みやすく、確実になる

C言語の学習では、変数、条件分岐、繰り返し、配列、ポインタなど、さまざまな文法を身につけていきます。しかし、実際のプログラム開発では、文法だけですべての処理を組み立てるわけではありません。

これまで使ってきた printf や scanf も、C言語の文法そのものではなく、あらかじめ用意されている関数です。このような、C言語の規格に基づいて利用できる関数を標準ライブラリ関数といいます。

標準ライブラリ関数を利用すると、次のような処理を簡潔に記述できます。

  • 画面に文字や数値を表示する
  • キーボードからデータを受け取る
  • 文字列の長さを調べる
  • 文字列をコピーしたり比較したりする
  • 文字が数字や英字かどうかを判定する
  • 英大文字と英小文字を変換する
  • 平方根やべき乗を計算する
  • 擬似乱数を生成する
  • 必要な大きさのメモリを実行中に確保する
  • 現在の日付や時刻を取得する

こうした処理を、すべて自分で一から作ることも不可能ではありません。しかし、同じような処理を毎回書いていると、プログラムが長くなり、間違いが入り込む可能性も高くなります。

標準ライブラリ関数は、頻繁に必要となる処理を使いやすい形にまとめたものです。どのような関数があり、どの場面で使えばよいのかを知ることは、C言語の文法を学ぶことと同じくらい大切です。

ここでは、標準ライブラリ関数の役割、ヘッダファイルとの関係、代表的な関数の種類、学習するときのポイントを順番に見ていきましょう。

標準ライブラリ関数とは

標準ライブラリ関数とは、C言語の規格によって機能や使い方が定められている関数です。

プログラマーは、必要な関数を呼び出すことで、よく使われる処理を簡単に実行できます。例えば、文字列の長さを調べる strlen を使うと、終端文字まで1文字ずつ調べるループを毎回書く必要がありません。

length = strlen(text);

この1行で、textが表す文字列の長さを取得できます。

標準ライブラリ関数は、C言語でプログラムを作るときに利用できる道具箱のような存在です。道具の名前と役割を知っていれば、必要な処理を効率よく組み立てられます。

ただし、すべての標準ライブラリ関数が自動的に利用できるわけではありません。多くの場合は、使いたい関数に対応したヘッダファイルをプログラムの先頭で読み込む必要があります。

図1:標準ライブラリ関数という道具箱

この図から分かること

標準ライブラリには、入出力、文字列操作、文字の判定、数学計算、メモリ管理、時刻処理など、目的別にさまざまな関数が用意されています。

必要な処理に合った関数を道具箱から選ぶように利用すれば、同じ機能を毎回自作する必要がありません。関数の種類を知ることは、プログラムを効率よく作るための第一歩になります。

標準ライブラリ関数を使う利点

標準ライブラリ関数を利用する主な利点は、効率性、信頼性、可読性、移植性の4つです。

利点内容
効率性よく使われる処理を短いコードで実現できる
信頼性広く利用されてきた定番の処理を活用できる
可読性関数名を見ることで処理の目的を理解しやすい
移植性C言語の規格に沿った関数を異なる環境でも利用しやすい

効率よくプログラムを書ける

文字列の長さを自分で調べる場合は、終端文字 \0 が現れるまで配列の要素を順番に確認し、変数を使って数える必要があります。

size_t length = 0;

while (text[length] != '\0') {
    length++;
}

この処理を strlen に置き換えると、次のように記述できます。

size_t length = strlen(text);

コードが短くなり、プログラマーは文字数を数える仕組みよりも、その長さを何に利用するのかという本来の目的に集中できます。

定番の処理を利用できる

自作した関数には、条件の見落としや境界位置の間違いが入る可能性があります。特に文字列やメモリを扱う処理では、小さなミスが大きな問題につながることもあります。

標準ライブラリ関数は幅広い環境で利用されているため、同じ機能をその都度自作するより、適切な関数を正しく利用するほうが安定したプログラムを作りやすくなります。

ただし、標準ライブラリ関数を使えば必ず安全になるわけではありません。引数の意味、配列の大きさ、戻り値などを確認し、関数の決まりに従って使うことが必要です。

プログラムの意図が伝わりやすい

関数名には、その関数が行う処理が表れています。

例えば、次の関数名からは、おおよその目的を読み取れます。

  • strlenは文字列の長さを調べる
  • strcmpは文字列を比較する
  • isdigitは数字文字かどうかを判定する
  • tolowerは英大文字を英小文字へ変換する
  • sqrtは平方根を求める

自分で複雑な処理を書くよりも、適切な関数を呼び出したほうが、コードを読む人に意図が伝わりやすくなります。

異なる環境へ移しやすい

標準ライブラリ関数は、C言語の規格に基づいて定められています。そのため、規格に対応した処理系であれば、Windows、Linux、macOSなど、異なる環境でも同じ考え方で利用できます。

環境固有の機能に頼る部分が少なくなるため、作成したプログラムを別の環境へ移すときにも再利用しやすくなります。

自作する処理と標準ライブラリ関数の違い

英大文字を英小文字へ変換する処理を考えてみましょう。

文字コードの並びを利用すると、次のような処理を書けます。

if (ch >= 'A' && ch <= 'Z') {
    ch = ch + ('a' - 'A');
}

このコードでは、chがAからZまでの範囲にあるかを調べ、大文字と小文字の文字コードの差を加えています。

多くの環境で利用されるASCII系の文字コードでは、この方法で英大文字を英小文字へ変換できます。しかし、コードを読んだ人は、条件式と計算式の意味を読み解かなければなりません。また、文字コードの並び方を前提とした書き方でもあります。

標準ライブラリ関数の tolower を利用すると、目的をより直接的に表現できます。

ch = tolower(ch);

tolowerという関数名から、英大文字を英小文字へ変換しようとしていることがすぐに分かります。

ctype.hで宣言されている文字判定・変換関数へ通常のchar型の値を渡すときは、char型が負の値になる環境にも注意が必要です。文字列から取り出した文字を安全に渡す書き方の一例は、次のとおりです。

ch = (char)tolower((unsigned char)ch);

初めのうちは基本的な使い方を理解し、その後、文字コードや型の扱いも少しずつ学んでいくとよいでしょう。

身近なものに置き換えて考えよう

標準ライブラリ関数は、市販のカレールーに置き換えて考えるとイメージしやすくなります。

カレーは、複数のスパイスを自分で選び、分量を調整して作ることもできます。この方法では自由に味を作れますが、知識と経験が必要です。また、毎回同じ味に仕上げるのも簡単ではありません。

市販のカレールーを利用すれば、スパイスを一から調合しなくても、少ない手順で安定した味のカレーを作れます。

C言語の標準ライブラリ関数にも、これと似た役割があります。処理の仕組みを自分で学ぶことは大切ですが、実際のプログラムでは、すでに目的に合った関数が用意されているなら、それを活用するほうが合理的です。

図2:カレールーで考える標準ライブラリ関数

この図から分かること

処理を一から作る方法には自由度がありますが、手順が増え、間違いが入り込む可能性も高くなります。

標準ライブラリ関数を使えば、目的に合った処理を短いコードで呼び出せます。市販のカレールーが料理の手間を減らして味を安定させるように、標準ライブラリ関数はプログラムの作成を効率化し、処理の意図を分かりやすくしてくれます。

ヘッダファイルとの関係

標準ライブラリ関数を使うときは、その関数に対応するヘッダファイルを読み込みます。

ヘッダファイルには、関数の名前、受け取る引数、返す値の型など、関数を正しく呼び出すために必要な宣言が記述されています。

主なヘッダファイルと関数の対応は次のとおりです。

ヘッダファイル主な関数主な用途
stdio.hprintf、scanf、puts、fgets標準入出力やファイル入出力
string.hstrlen、strcpy、strcmp、strcat文字列やメモリの操作
ctype.hisdigit、isalpha、toupper、tolower文字の判定や変換
math.hsqrt、pow、sin、cos数学計算
stdlib.hmalloc、free、rand、atoiメモリ、変換、乱数などの汎用処理
time.htime、clock、strftime日付や時刻の処理

例えば、printfとstrlenを使うプログラムでは、次のようにstdio.hとstring.hを読み込みます。

#include <stdio.h>
#include <string.h>

#includeは、指定したヘッダファイルの内容をプログラムへ取り込むためのプリプロセッサ指令です。

ヘッダファイルが必要な理由

コンパイラは、関数を呼び出すときに次のような情報を確認します。

  • 関数名が正しいか
  • どのような型の引数を渡すのか
  • 引数はいくつ必要か
  • 戻り値がどの型なのか

例えば、strlenは文字列の先頭を受け取り、その長さをsize_t型の値として返します。string.hを読み込むことで、コンパイラはstrlenの正しい形式を把握できます。

必要なヘッダファイルを読み込まないまま関数を呼び出すと、コンパイラが正しく確認できず、警告やエラーの原因になります。

ヘッダファイルは、単に関数名を使えるようにするための付属品ではありません。関数を正しい形式で呼び出すための案内書として重要な役割を持っています。

文字列の表示と長さを調べるプログラム

ここでは、標準ライブラリ関数のputs、printf、strlenを組み合わせ、メッセージの表示と文字列の長さの取得を行います。

日本語を含む文字列では、利用する文字コードによってstrlenが返すバイト数が変わることがあります。基本動作を分かりやすく確認できるように、今回は半角英数字の文字列を使用します。

英文メッセージを表示して長さを調べるプログラム
#include <stdio.h>
#include <string.h>

int main(void)
{
    char message[] = "Learn C Library";

    /* メッセージを表示する */
    puts(message);

    /* 文字列の長さを取得する */
    size_t length = strlen(message);

    /* 取得した長さを表示する */
    printf("文字列の長さは%zuです。\n", length);

    return 0;
}

ファイル名:12_1_1.c

実行結果の例
Learn C Library
文字列の長さは15です。

プログラムで使用している標準ライブラリ関数

関数名ヘッダファイル役割
putsstdio.h文字列を表示した後に改行する
strlenstring.h終端文字の直前までのバイト数を求める
printfstdio.h指定した書式に従って文字列や値を表示する

ヘッダファイルを読み込む部分

#include <stdio.h>
#include <string.h>

stdio.hは、putsとprintfを使うために読み込んでいます。string.hは、strlenを使うために必要です。

利用する関数と、それを宣言しているヘッダファイルを組み合わせて覚えることが大切です。

文字配列を用意する部分

char message[] = "Learn C Library";

messageという文字配列を宣言し、文字列Learn C Libraryで初期化しています。

配列の末尾には、文字列の終わりを表す終端文字\0が自動的に格納されます。

配列の内容は、次のような並びになります。

L e a r n   C   L i b r a r y \0

空白も文字列を構成する1バイトとして数えられますが、末尾の\0は文字列の長さに含まれません。

putsで文字列を表示する部分

puts(message);

putsは、引数として受け取った文字列を画面に表示し、最後に改行します。

printfを使って次のように書くこともできます。

printf("%s\n", message);

単純に文字列を表示して改行したい場合は、putsを利用すると目的を簡潔に表せます。

strlenで長さを取得する部分

size_t length = strlen(message);

strlenは、文字列の先頭から終端文字\0の直前までを調べ、その長さを返します。

戻り値の型はsize_tです。そのため、結果を受け取るlengthもsize_t型で宣言しています。

Learn C Libraryには、英字13文字と空白2文字が含まれているため、strlenが返す値は15です。

strlenは、配列全体の大きさを調べる関数ではありません。文字列の終端文字が見つかるまでの長さを調べる関数です。そのため、strlenに渡す文字配列には、正しい位置に終端文字が必要です。

printfで長さを表示する部分

printf("文字列の長さは%zuです。\n", length);

printfの変換指定子%zuは、size_t型の値を表示するときに使用します。

strlenの戻り値を表示するときは、戻り値の型に対応する%zuを使うと覚えておきましょう。

日本語文字列をstrlenで調べる場合の注意

strlenが返すのは、画面上で見える文字の個数ではなく、終端文字の直前までに使われているバイト数です。

例えば、UTF-8では一般的な日本語1文字が複数バイトで表現されます。そのため、日本語を含む文字列にstrlenを使った結果は、人が数える文字数と一致しないことがあります。

この段階では、次の違いを押さえておくとよいでしょう。

  • strlenは文字列のバイト数を返す
  • 終端文字 \0は長さに含めない
  • 日本語の見た目の文字数とは一致しないことがある

主な標準ライブラリ関数の種類

C言語には多くの標準ライブラリ関数があります。すべてを一度に暗記する必要はありません。まずは、どのような分野の関数が用意されているのかを理解しましょう。

標準入出力関数

標準入出力関数は、画面への表示やキーボードからの入力などに使用します。主な関数はstdio.hで宣言されています。

関数名説明
printf書式を指定して文字列や数値を出力する
scanf書式を指定してデータを入力する
putchar1文字を出力する
getchar1文字を入力する
puts文字列を出力した後に改行する
fgets最大文字数を指定して1行分の文字列を入力する

printfは、数値や文字列を組み合わせて表示するときに便利です。putsは、文字列をそのまま表示して改行したいときに簡潔に使えます。

入力ではscanfも利用できますが、文字列を1行単位で安全に受け取りたい場合は、読み込む最大文字数を指定できるfgetsも重要です。

文字列操作関数

文字列操作関数は、主にstring.hで宣言されています。

関数名説明
strlen文字列の長さを取得する
strcpy文字列を別の配列へコピーする
strncpy指定した最大数を基準に文字をコピーする
strcat文字列の末尾に別の文字列を連結する
strncat追加する最大文字数を指定して連結する
strcmp2つの文字列を辞書順に比較する
strncmp指定した最大文字数の範囲で比較する
strchr文字列の中から指定した文字を探す
strstr文字列の中から指定した部分文字列を探す

C言語では、文字列をchar型の配列として扱います。そのため、コピー、比較、検索、連結といった操作では、文字列操作関数が大きな助けになります。

ただし、コピー先や連結先の配列に十分な領域がないと、配列の範囲を超えて書き込む危険があります。文字列操作関数を使うときも、配列の大きさを確認することが重要です。

また、strncpyは指定した数の範囲でコピーしますが、条件によってはコピー先の末尾へ終端文字を格納しない場合があります。関数名だけで安全だと判断せず、細かな動作を確認して使いましょう。

文字の判定・変換関数

文字の判定や変換を行う関数は、ctype.hで宣言されています。

関数名説明
isalpha英字として扱われる文字か判定する
isdigit0から9までの数字文字か判定する
isalnum英字または数字文字か判定する
isupper英大文字として扱われる文字か判定する
islower英小文字として扱われる文字か判定する
isspace空白類の文字か判定する
toupper英小文字を英大文字へ変換する
tolower英大文字を英小文字へ変換する

これらの関数は、入力された文字を確認したり、表記を統一したりするときに役立ちます。

例えば、ユーザーが入力した文字が数字なら処理を続け、数字でなければエラーメッセージを表示するといった使い方ができます。

判定関数は、条件に該当する場合に0以外の値を返し、該当しない場合に0を返します。必ず1が返るとは限らないため、次のように真偽を判定します。

if (isdigit((unsigned char)ch)) {
    printf("数字です。\n");
}

数学関数

数学関数は、主にmath.hで宣言されています。

関数名説明
sqrt平方根を求める
powべき乗を求める
sin正弦を求める
cos余弦を求める
tan正接を求める
fabs実数の絶対値を求める
ceil小数部を切り上げる
floor小数部を切り捨てる

数学関数を使えば、複雑な計算を短い式で表せます。

例えば、25.0の平方根は次のように求められます。

double answer = sqrt(25.0);

2.0の3.0乗は、powを使って次のように計算できます。

double answer = pow(2.0, 3.0);

開発環境によっては、math.hの関数を使用したプログラムをコンパイルするときに、数学ライブラリをリンクするための指定が必要になる場合があります。

一般ユーティリティ関数

幅広い目的に利用できる関数は、主にstdlib.hで宣言されています。

関数名説明
malloc指定したバイト数のメモリ領域を動的に確保する
free動的に確保したメモリ領域を解放する
atoi文字列をint型の整数へ変換する
atof文字列をdouble型の実数へ変換する
rand擬似乱数を生成する
srand擬似乱数を生成するための初期状態を設定する
qsort配列の要素を指定した規則で並べ替える
absint型の整数の絶対値を求める

mallocとfreeは、プログラムの実行中に必要な大きさのメモリを確保し、不要になったら解放するために使います。ポインタと動的メモリを学習するときに欠かせない関数です。

randとsrandは、ゲーム、抽選、簡単なシミュレーションなどで擬似乱数が必要なときに利用できます。

atoiは簡単に変換できますが、変換に失敗した場合を細かく判定できません。入力内容を確実に検査したい場合には、より詳細な確認ができるstrtolなどを学ぶことになります。まずは、文字列を数値へ変換する関数がstdlib.hに用意されていることを理解しましょう。

時間関数

時刻や処理時間を扱う関数は、time.hで宣言されています。

関数名説明
time現在の暦時刻を取得する
clockプログラムが使用した処理時間を取得する
difftime2つの暦時刻の差を計算する
strftime日付や時刻を指定した書式の文字列へ変換する

時間関数を使うと、現在日時の表示、処理時間の測定、開始時刻と終了時刻の差の計算などを行えます。

timeで取得した値は、そのままでは人が読みやすい年月日や時分秒になっていません。必要に応じてほかの時間関数と組み合わせ、表示しやすい形へ変換します。

最初に覚えたい関数

標準ライブラリ関数は数が多いため、使用頻度の高いものから覚えていくと効率的です。

分野最初に覚えたい関数
入出力printf、puts、scanf、fgets
文字列strlen、strcmp、strcpy
文字の判定・変換isdigit、isalpha、toupper、tolower
数学計算sqrt、pow
乱数rand、srand
動的メモリmalloc、free

最初は、それぞれの関数について次の3点を確認しましょう。

  • 何をする関数なのか
  • どのヘッダファイルで宣言されているのか
  • どのような引数と戻り値を持つのか

この3点をセットで理解すると、必要な場面で適切な関数を選びやすくなります。

標準ライブラリ関数を学ぶコツ

標準ライブラリ関数は、一覧を眺めて丸暗記するだけでは身につきにくいものです。実際に短いプログラムで試しながら、使い方を確認していきましょう。

関数が担当する仕事をつかむ

最初に、関数が何をするものなのかを短い言葉で整理します。

  • strlenは文字列の長さを調べる
  • strcmpは2つの文字列を比較する
  • isdigitは数字文字か判定する
  • toupperは英小文字を英大文字へ変換する
  • sqrtは平方根を求める

細かな仕様を最初からすべて覚える必要はありません。まずは、必要になったときに候補となる関数を思い出せる状態を目指しましょう。

ヘッダファイルと組み合わせて覚える

関数名だけではなく、対応するヘッダファイルも一緒に覚えます。

  • printfとstdio.h
  • strlenとstring.h
  • tolowerとctype.h
  • sqrtとmath.h
  • mallocとstdlib.h
  • timeとtime.h

関数を使おうとしたときに必要なヘッダファイルが分からなければ、コンパイル時の警告やエラーにつながります。関数名とヘッダファイルを一組として整理すると、実際のプログラムで使いやすくなります。

引数と戻り値を確認する

標準ライブラリ関数には、受け取る値と処理結果の返し方が決められています。

例えば、strlenでは次のように考えられます。

確認項目strlenの場合
引数長さを調べる文字列の先頭
処理終端文字\0までの長さを調べる
戻り値終端文字を除いたバイト数
戻り値の型size_t
ヘッダファイルstring.h

関数を使う前に、引数、戻り値、ヘッダファイルを確認する習慣をつけると、間違った使い方を減らせます。

小さなプログラムで動作を試す

1つのプログラムに多数の関数を詰め込むより、1回の練習で1つか2つの関数を試すほうが、動作を理解しやすくなります。

例えば、次のような小さな課題が適しています。

  • 入力した文字が数字かどうかをisdigitで判定する
  • 入力した英字をtoupperで英大文字へ変換する
  • 2つの文字列をstrcmpで比較する
  • 文字列の長さをstrlenで表示する
  • sqrtで平方根を計算する
  • randで複数の擬似乱数を表示する

実行前に結果を予想し、実行結果と比較すると、関数の理解がさらに深まります。

図3:標準ライブラリ関数を身につける学習手順

この図から分かること

標準ライブラリ関数は、名前だけを暗記するのではなく、目的、関数、仕様、動作確認という順序で学ぶと理解しやすくなります。

まず何を実現したいのかを明確にし、それに合う関数を探します。次に、必要なヘッダファイル、引数、戻り値、注意点を確認し、短いプログラムで実際に動かします。この流れを繰り返すことで、必要なときに適切な関数を選ぶ力が身についていきます。

標準ライブラリ関数を使うときの確認事項

標準ライブラリ関数は便利ですが、関数名だけを見て使うと、思わぬ問題が発生することがあります。利用するときは、少なくとも次の項目を確認しましょう。

  • 必要なヘッダファイルを読み込んでいるか
  • 引数の個数と型が正しいか
  • 戻り値の型と意味を理解しているか
  • 処理に失敗した場合の戻り値を確認したか
  • 文字配列やメモリ領域に十分な大きさがあるか
  • 文字列の末尾に終端文字\0があるか
  • 確保したメモリを不要になった時点で解放しているか
  • 使用する開発環境で追加のリンク指定が必要か

特に、文字列操作と動的メモリ操作では、配列や領域の大きさを意識することが重要です。

標準ライブラリ関数は、正しい使い方をすれば開発を大きく助けてくれます。しかし、関数がすべての安全確認を自動的に行ってくれるわけではありません。仕様を確認し、引数と戻り値を理解したうえで利用しましょう。

用意された関数を活用する意識を持とう

C言語では、処理を自分で組み立てる力と、すでに用意されている機能を選んで活用する力の両方が必要です。

仕組みを理解するために、文字列の長さをループで数えたり、大文字と小文字の変換処理を自分で書いたりすることには学習上の価値があります。一方、実用的なプログラムを作る場面では、目的に合った標準ライブラリ関数を利用するほうが、コードを短く、分かりやすく、再利用しやすくできます。

プログラムを書いている途中で、よく見かける処理が必要になったときは、次のように考えてみましょう。

  • 同じ処理を行う標準ライブラリ関数はないか
  • どのヘッダファイルに用意されているか
  • 引数と戻り値はどのように定められているか
  • 配列の大きさや失敗時の処理に注意が必要か

標準ライブラリ関数を知ることは、単に便利な関数名を増やすことではありません。必要な機能を見つけ、仕様を確認し、適切に組み合わせてプログラムを作る力を身につけることです。

文法と標準ライブラリ関数を一緒に使えるようになると、C言語で表現できる処理の幅が大きく広がります。