
C言語基礎|printf関数の形式
printfの…(ドット3つ)は魔法の入口!書式文字列と戻り値で、出力の仕組みを“手に取るように”理解しよう。
printf は、C言語の「表示担当」なのに、奥が深い関数です。
なぜかというと、printf は第2引数以降が可変で、型チェックがゆるくなりやすいからです。
でも安心してください。ポイントはシンプルで、
- 第1引数の書式文字列が “指令書”
- 第2引数以降は “材料(値)”
- 戻り値は “出力できた文字数(失敗なら負)”
この3つを押さえるだけで、printf はグッと扱いやすくなりますよ。
printf関数の形式(命令の書式)
形式
int printf(const char * restrict format, ...);
図:引数のイメージ
printf( 書式文字列, 値1, 値2, 値3, ... );
↑ 指令書 ↑ 指令書に埋め込む材料(可変個)
図の説明
- 書式文字列の中にある %d や %f などが「ここに値をはめ込んでね」という指令になります。
- 値は必要なだけ渡せます(... の部分)。
...(省略記号)が意味すること
... は「この関数は引数をいくつでも受け取れるよ」というサインです(可変長引数)。
... の特徴
| 項目 | 内容 | 重要ポイント |
|---|---|---|
| 役割 | 第2引数以降を可変個にする | 引数の個数が決まらない |
| 型 | いろいろ渡せる | ただし型不一致は危険 |
| チェック | コンパイラが完全には守れない | 書式と型を合わせる習慣が大事 |
表の説明
- 便利な反面、書式文字列と実引数の型がズレると未定義動作になりやすいです。
- だからこそ「書式文字列=指令書」という意識が大切なんですね。
戻り値:出力した文字数(失敗なら負)
printf は成功すると「出力した文字数」を返します。失敗すると負の値です。
図:戻り値の考え方
w = printf("ABC\n");
w は 4(A,B,C,改行 の4文字)になることが多い
失敗したら w は負の値
図の説明
- 戻り値は「実際に何文字出せたか」の結果報告です。
- ふだん無視しても動きますが、“出力が成功したか” を確認したいときに役立ちます。
サンプルプログラム(別のシンプル例 / 日本語メッセージ / 日本語コメント)
「幅が足りるか」を printf の戻り値で判定してみます。
3桁の枠 %3d に数値を入れ、出力文字数で “枠に収まったか” を見ます。
プロジェクト名:chap13-13-1 ソースファイル名:chap13-13-1.c
#include <stdio.h>
int main(void)
{
int x;
printf("整数を1つ入力してください:");
/* 入力が成功したかを確認する */
if (scanf("%d", &x) != 1) {
printf("入力エラー:整数を入力してください。\n");
return 1;
}
/* 幅3で表示して、実際に何文字出たかを調べる */
printf("幅3で表示:");
int w = printf("%3d", x);
printf("\n");
/* printfの戻り値で状態を判断する */
if (w < 0) {
printf("出力エラーが発生しました。\n");
} else if (w == 3) {
printf("ちょうど3文字で表示できました(3桁以内の可能性が高いです)。\n");
} else {
printf("3文字を超えて表示されました(枠より大きい数です)。\n");
}
return 0;
}実行イメージ
- 入力:7 → %3d は空白2つ+7 なので 3文字
- 入力:1234 → 1234 とそのまま出て 4文字(切り捨てされない)
%3d が「3桁に切り捨てない」理由
「幅」は 最小フィールド幅 です。
足りなければ枠を広げて出力します。削りません。
図:最小フィールド幅の挙動
%3d に 7 → "__7" (3文字)
%3d に 123 → "123" (3文字)
%3d に 1234 → "1234" (4文字:枠が広がる)
図の説明
- だから w == 3 は “3桁以内っぽい” の目安になります。
- ただし負数だと -7 が2文字、-123 が4文字など、符号で変わるので注意です。
printfの「書式文字列」と「実引数」の対応
printf は書式文字列を左から読み、変換指定(%から始まる指定)に出会うたびに、次の実引数を1つ使います。
対応の基本ルール
| 書式文字列の要素 | 何が起きる? | 実引数を消費する? |
|---|---|---|
| 普通の文字(例:こんにちは) | そのまま出力 | しない |
| 変換指定(例:%d) | 実引数を文字列に変換して出力 | する(1個) |
| %% | % を出力 | しない |
表の説明
- 変換指定の数と、渡す値の数が合っていないと危険です。
- 多すぎるのは無視されがちですが、少なすぎるのは特に危険です。
restrict って何?
宣言にある restrict は「このポインタが指す領域は、他のポインタと重ならないよ」という最適化のための約束です。
printfにおける restrict の受け止め方
| 観点 | 説明 |
|---|---|
| 実務的な影響 | ふつうの printf 利用では気にしなくてOK |
| 意味 | format が指す領域と他の参照が衝突しない前提で最適化できる |
| 初学者の優先度 | 低(まず書式と戻り値を優先) |
表の説明
- printfを使う側としては、まず「書式文字列」「変換指定」「戻り値」を押さえるのが一番効きます。
printfの戻り値を活かす場面
戻り値が役立つケース
| やりたいこと | 使い方の例 | うれしい点 |
|---|---|---|
| 出力が成功したか知りたい | if (printf(...) < 0) | エラー検出ができる |
| 表示幅の目安を取りたい | w = printf("%3d", x) | 実際の文字数で判断できる |
| ログの整形結果を検査したい | w と期待値を比較 | 想定外の出力を見つけられる |
表の説明
- 「印字できた文字数」という情報は、出力の検証や表示整形のチェックに使えます。
