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 と期待値を比較想定外の出力を見つけられる

表の説明

  • 「印字できた文字数」という情報は、出力の検証や表示整形のチェックに使えます。