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の実行画面
実行画面とコードの対応をよく考えてみてください。