Cによるプログラミング入門3
変数、printf、scanf

 今回は、「データのいれもの」について紹介します。プログラミングの世界では、「データのいれもの」を変数とよぶのですが、初心者には案外わかりにくいものです。逆に、わかってしまえば簡単で、経験者が初心者に対して「どうしてこれがわからないのだろう」と悩んでしまったりもするのです。(それで、初心者が自信をなくしたりするのですが、みなさんはそうならないようにしましょう。どうってことはないんです。)
 いつもそうなのですが、途中で立ち止まらずに、ざっと解説を読んで、サンプルプログラムをコンパイル・実行してみててください。基本的に、「こういうコードを書くとこうなる」という形を見て、それから考えたほうが、効率的だと思います。


 前回のプログラムは、決められた文字列を出力だけでした。しかし、一般的なプログラムでは、データを扱うことになります。そのためには、「データのいれもの」が必要ですね。
 まず、簡単な例を見てみましょう。たとえば、「整数データのいれもの」は次のように作ります。

int x;

 これで、「xという名前の整数のいれもの」ができたことになります。intが「整数」という意味なのです。この「いれもの」に、5という整数をいれたければ、

x = 5;

などとします。「x = 5」は「xは5に等しい」ではなく「xに5を代入せよ」という意味であることに注意してください。そういうものなのです。また、

int x = 5;

のように書くと、「xという名前の整数のいれものを作り、最初にその中に5をいれておく」という意味になります。


 さて、一般に、データの「いれもの」をは、変数といい、その種類をといいます。そして、変数は

型 変数;

という形で用意する(作る)のです。(これを「変数を定義する」といいます。)また、変数に最初から値をいれておきたければ、

型 変数 = 値;

とします。これで、「変数を定義し、その際に値を格納する」ということになるわけです。
 最初に見せた例と見比べてください。intが型で、xが変数です。ちゃんと、そういう形になっていますよね。これを「xはint型の変数」などともいいます。
 なお、型名や変数名は半角英数字で書きます。(基本的な)型名は決められているので、変えることはできませんが、変数名はプログラマが勝手につけてよいもので、1文字でなくてもかまいません。
 ただし、変数名は、ifだとかforだとか、特別なキーワード(あとで説明します)と一致しないようにする必要はあります。また、数字も使えますが、最初の1文字目は文字かアンダーバー「_」とします。(「規則をおぼえなきゃ」と思うと大変ですが、サンプルをいじっているうちに、感覚でわかってきますので、心配しないでください。)
 int以外に、どんな型があるかは、おいおい説明します。

 それでは、変数の内容を表示するにはどうすればよいでしょうか?これも例を見てから考えましょう。

/* hensu.c */
#include <stdio.h>

int main(void)
{
    int x = 5;
    printf("%d", x);
    return 0;
}

上のプログラムをコンパイルし、実行すると、画面には5と表示されます。

Fig.1 hensu.cをコンパイル(コンパイル+リンク)して生成したhensu.exeを実行

 まず、今回から、コメントというものを使います。これは、プログラム中に埋め込まれた注釈のことで、プログラムの動作そのものにはなんの影響も与えません。これは、主として、プログラムを読む他人(あるいは、時間が経ってからの自分)の理解を助けるためにいれるものです。
 一般に、「コメントは、短く適切なもののみを入れるべき」と言われています。しかし、この講座では、コメントを本文の補助として、大量に使います。これはあくまで、「教科書だから」と考えてください。
 Cにおけるコメントは、

/* コメント */

のように書きます。ここでコメントは、何行あってもかまいません。
 また、

// コメント

というスタイルのコメントもあります。これは、//のある行について、「//の後の部分」がコメントになるのです。これは、C++の流儀ですが、多くのコンパイラがCとC++共用であるため、こちらのスタイルも使えるようになっていると思います。
 上のプログラムは、プログラム名をコメントに入れました。「/* hensu.c */」の部分です。

 上のプログラムhensu.cは、コメントを除くと、前回紹介した、「プログラムの基本形」にしたがっていることに注意してください。最初に「#include <stdio.h>」があり、次に

int main(void)
{
    ...
}

とあり、この中カッコの中身が、「プログラムの中心の中身」であるわけです。

 mainの1行目の「int x = 5;」は、「メモリ内に整数のいれものxを確保し、そこに5を入れる」だけなので、画面には何も表示されません。画面に何かを表示するのは、次の行のprintfです。
 printfは、前回、「文字列を出力する」と説明しました。そういうものなのです。ただし、次のように考えてください。

printf("...%d...", x);

のように使われると、「...%d...の%dの場所にxの値を埋め込んだ文字列」を出力するのです。
 ただし、hensu.cでは、「...」部分が何もなかったので、ただ「5」だけを出力したわけです。それでは、次のプログラムを試してみてください。

/* hensu2.c */
#include <stdio.h>

int main(void)
{
    int x = 5;
    printf("変数の中身は%dです。\n", x);
    return 0;
}

 こうすると、「変数の中身は%dです。\n」の「%d」のところに5が埋め込まれた文字列が出力されるのです。

Fig.2 hensu.exeの実行画面


 もちろん、hensu.cやhensu2.cは、自分で決めた数を表示しているだけなので、あまりおもしろくはありません。これを少しだけおもしろくするために、ユーザに整数を入力してもらいたいと思います。
 それには、scanfという関数が使えます。(Cでは何かするものを「関数」というのでした。)

scanf("%d", &x);

とすると、「ユーザの整数入力を待ち、入力があれば、それをxに格納する」という意味になるのです。ここで、「%d」は「入力待ちが整数であること」を意味し、&xは、「入力された値をxに格納する」という意味なのです。ここで、「なんで&なんかがあるの?」と思うかもしれませんが、とりあえず、そういうものだと思ってください。
 scanfを使って、次のようなプログラムが書けます。これは、ユーザに整数を入力させ、その入力した値をxに格納し、それを表示するプログラムです。
 ただし、変数の定義は「ブロックの最初に行う」というルールがあります。今の場合、ブロックとはmainの中身のことです。(実は、mainの中身以外にもコードが書けるのです。それは、また、あとのお楽しみ。)その点にも注意してください。

/* hensu3.c */
#include <stdio.h>

int main(void)
{
    int x;
    printf("整数を入力してください:");
    scanf("%d", &x);
    printf("あなたが入力した値は%dですな。\n", x);
    return 0;
}

 プログラムとしてはまだおもしろくないですが、重要な箇所なので、少しゆっくり見ておいてください。実行画面は次のようになります。

Fig.3 hensu3.exeの実行画面

 例によって、mainの1行目は、変数を定義しているだけなので、何も出力しません。
 2行目のprintfは「整数を入力してください:」を出力します。ここで""の中の最後に「\n」を入れなかったことに注意してください。これにより、「整数を入力してください:」を出力したあとに改行されないのです。
 3行目はscanfですね。これで、「ユーザからの入力を待ち、入力された整数をxに格納する」という命令になるのです。scanfが実行されると、「ユーザの入力待ち状態」になるので、プログラムの実行がいったん停止したようになります。つまり、「整数を入力してください:」が出力されたあとに、プログラムは「停止して」ユーザーの入力を待つのです。そして、最初のprintfでは「\n」を使わず、改行をしなかったので、ユーザの入力は「整数を入力してください:」と同じ行に出ることになります。
 3行目でユーザが整数を入力すると、その値がxに格納され、すぐに次の行が実行されます。Fig.3の実行例では、ユーザは100と入力しています。そこで、最後の行が実行されるとき、xには100が格納されているのです。printfの「%d」のところに、xの値が埋め込まれるので、結局、「あなたが入力した値は100ですな。」となるわけです。


 今日のポイントはほぼ終わりました。あと、もう少し、つけたしです。
 変数が複数ほしくなったら、「型 変数;」を複数回書きます。あるいは、

型 変数1, 変数2, ... ;

とすることもできます。たとえば、

int x, y, z;

とすれば、x、y、zというint型変数が定義されたことになるのです。ユーザからの入力をこれらに受け取るのに、scnafを3回繰り返してもかまいませんが、

scanf("%d %d %d", &x, &y, &z);

のように書くこともできます。こうすると、ユーザが空白を間に入れて3つの整数を同時に入力することができるのです。(「%d」は整数を表わしているのです。そして変数が3つあるから、「%d」も3つ書いているわけです。また、「%d」の間に空白をいれたので、「空白で区切った整数」の入力を待つことになるわけです。
 つまり、上のようなコードに対して、

100 200 300

などと(1行で)入力すると、x、y、zに、それぞれ100、200、300が格納されるのです。
 次のプログラムを見てください。

/* hensu4.c */
#include <stdio.h>

int main(void)
{
    int x, y, z;
    printf("整数を3つ、空白で分けて入力してください。\n");
    scanf("%d %d %d", &x, &y, &z);
    printf("1つ目は%d、2つ目は%d、最後の整数は%dでした。\n", x, y, z);
    printf("それらの合計は%dです。\n", x + y + z);
    return 0;
}

 mainの1行目で3つのint型変数x、y、zを用意し、3行目のscanfでユーザの入力を3つ同時に受け取り、それらを変数に格納しています。
 4行目は、それらの出力ですね。このように書くと、「1つ目は%d、2つ目は%d、最後の整数は%dでした\n」内の「%d」のところに、x、y、zの値が順番に埋め込まれたものが出力されるのです。これも、ここでおぼえましょう。
 最後のprintfの「文字列部分」は「それらの合計は%dです。」ですね。「%d」は一箇所しかないので、出力される整数も1つです。実際、この行では、「x + y + z」(つまり、3つの変数の持つ値の和)が、そこに出力されるのです。このように、足し算などで新しい値を生成(計算)できるのです。

Fig.4 hensu4.exeの実行画面

 実行画面とコードの対応をよく考えてみてください。

課題3


C入門目次

前のページ  後のページ