
C言語基礎|scanf関数とポインタ
scanfで & を付ける理由、ちゃんと説明できますか?「住所を渡す」感覚が身につくと入力処理が怖くなくなる。
printf は「表示してね」と頼む関数、scanf は「ここに書き込んでね」と頼む関数。
この違いが分かると、scanf の呼び出しで変数の前に & を付ける理由がスッと理解できます。
scanf は、キーボードから読んだ値を 呼び出し側が用意した変数(オブジェクト)に格納しないといけません。
つまり、scanf には「値」じゃなくて「格納先の住所(アドレス)」を渡す必要があるんです。
この住所の箱に、入力した値を入れてください!
このお願いをするために、& を付けて住所を渡します。
printf と scanf の違い(何を渡して何をしてもらう?)
まずは対比で整理すると理解が一気にラクになります。
printf と scanf の依頼内容の違い
| 関数 | 目的 | 渡すもの | 依頼の言い方(イメージ) |
|---|---|---|---|
| printf | 画面に出す | 値 | この値を表示してください |
| scanf | 変数に入れる | 住所(ポインタ) | この箱に書き込んでください |
なぜ scanf は住所が必要?(値だけだと書き込めない)
もし scanf に「値」を渡しても、scanf から見れば「ただの数字」であって、どこに書けばいいか分かりません。
そこで住所(アドレス)を渡します。
scanf が欲しいのは格納先の場所

サンプルプログラム
入力した2つの数の合計を表示する超シンプルなプログラム例です。
プロジェクト名:chap10-8-1 ソースファイル名:chap10-8-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
#include <stdio.h>
int main(void)
{
int a, b;
puts("2つの整数を入力してください。");
printf("a = ");
scanf("%d", &a);
printf("b = ");
scanf("%d", &b);
printf("合計は %d です。\n", a + b);
return 0;
}scanf の書式(命令の書式)と何をする命令なのか
scanf は「入力を読み取って、指定された場所に格納する」関数です。
scanf の基本形
- 書式:scanf(書式文字列, 格納先1, 格納先2, ...);
ここでいう「格納先」は多くの場合 変数のアドレスです。
例:整数を1つ読む
- scanf("%d", &a);
意味はこうです。
- %d:整数として読み取る
- &a:a の住所(ここに書き込んでね)
&(アドレス演算子)を付ける理由
& は、変数の住所(アドレス)を取り出す演算子です。
& を使う場面
| 式 | 意味 |
|---|---|
| a | a の値 |
| &a | a の住所(ポインタ) |
scanf は「住所」を渡してほしいので、&a が必要になります。
printf の呼び出しと scanf の呼び出し
同じ変数 i を例に、依頼の内容が違うことを見える化します。
printf の依頼(値を渡す)
printf("%d", i);
i の値が 15 なら
「15 を表示してください」
scanf の依頼(住所を渡す)
scanf("%d", &i);
i の住所が 0x1000 なら
「0x1000 の箱に整数を書き込んでください」
図のポイントはこれです。
- printf は「読むだけ」なので値でOK
- scanf は「書き込む」ので住所が必要
scanf の戻り値(地味に大事)
scanf は、読み取りに成功した項目数を返します。
入力エラーに強いプログラムを書くなら、ここを見るのが基本です。
scanf の戻り値
| 戻り値 | 意味 |
|---|---|
| 1 | 1個の入力に成功 |
| 2 | 2個の入力に成功(scanf("%d%d", ...) など) |
| 0 | 変換に失敗(数字が必要なのに文字が来た等) |
| EOF | 入力終了(環境による) |
※今回は入門として動作理解が目的なので、戻り値チェックは発展として覚えておくとOKです。
よくある間違い(& の付け忘れ)
これをやると、scanf は「書き込み先の住所」を受け取れません。結果は未定義になりやすく危険です。
NG例
scanf("%d", a); // & がない
何が渡ってしまう?
| 書き方 | scanf が受け取るもの | 結果 |
|---|---|---|
| scanf("%d", &a) | a の住所 | 正しく書き込める |
| scanf("%d", a) | a の値(未初期化ならゴミ) | どこに書くか分からず危険 |
空ポインタ(null pointer)と NULL
ここからは「ポインタ全体の基礎知識」として、NULL の話を整理します。
空ポインタとは
何も指さないことが保証された特別なポインタです。
「有効なオブジェクトの住所ではない」という意味で、安全な“無”の表現になります。
NULL とは
NULL は「空ポインタ」を表すための マクロです。
多くの環境でヘッダを取り込むと使えます(stdio.h でも使えることが多いです)。
NULL の位置づけ
| 用語 | 意味 |
|---|---|
| 空ポインタ | 何も指さないポインタ |
| NULL | 空ポインタを表すマクロ(空ポインタ定数) |
定義の一例として NULL が 0 っぽく書かれていることがありますが、プログラムでは「空ポインタとして扱う」意識が大切です。
使った表や図の説明(まとめ)
- printf と scanf の表は「値を渡すのか、住所を渡すのか」を対比するための整理です。
- 対比図(図A/図B)は、同じ i を使って「表示」と「書き込み」の違いを直感でつかむためのものです。
- 戻り値表は、scanf が成功したかどうかを確認する基礎知識として追加しました。
- NULL の表は「空ポインタ」と「NULL(マクロ)」を混同しないための整理です。
