Part.3

変数

内容

  • コメント文と字下げ(読みやすいソースプログラム)
  • 変数
  • C言語における変数の宣言と変数の使用
  • printf 関数を使って変数の内容を画面に表示する

目標

プログラミング言語には必ず存在する”変数”を理解し使えるようになってもらいます.具体的には,以下のような内容をしっかり身に付けてください.

  • 変数の宣言
  • 変数への数値の代入
  • 変数内の数値を画面に表示(printf 関数)
  • 変数内に数値をキーボードを使って入力(scanf 関数)

Part2の復習

#include <stdio.h>

int main()
{
    printf("Hello!\n");
}

Part2では,上のサンプルソースプログラムを使って,次の事柄を学習しました.

  • Cのプログラムは関数で構成される
  • Cのプログラムには main 関数が必要である
  • 関数の有効範囲は { から } までである
  • printf は画面に文字列を表示するための標準関数である
  • \n は改行(復改)を意味する
  • プログラムの先頭には「#include <stdio.h>」を必ず書く
  • 文末にはセミコロン ; が必要である
  • C言語の文法に従わないプログラムはコンパイル時にエラーとなる

なお,Cコンパイラーを使うとき,

cc  hello.c  -o  hello

と書きましたが,これは hello.c というファイル名のソースプログラムから hello という名前のプログラムを作成する(hello.c という名前のC言語のソースプログラムを hello という名前の機械語プログラムに翻訳する)という意味です.つまり,

cc  hello.c  -o  bye

という使い方も可能ですが,通常はソースプログラムのファイル名と実行プログラム名は同じ名前(.c はとりますが)にします.上記のようにコンパイルした場合,プログラムを実行するには

./bye

とします.

Part2の課題3の解答例

#include <stdio.h>

int main()
{
    printf("Hello!\n");
    printf("My name is Ueyama.\n");
    printf("How are you?\n");
}

確認問題1

次の4行の文字列を画面に表示するプログラムを作成せよ(3行目は空白行).ただし,printf 関数は1度しか用いない事.

This is a 1st line.
This is a 2nd line.

This is a 4th line.

確認問題2

次の1行の文字列を画面に表示するプログラムを作成せよ.ただし,printf関数を3度用いる事.

This is a 1st line.

コメントと字下げ

コメント

C言語では,ソースプログラムを読みやすくするために,コメントを書き込むことができます.コメントは /* と */ で囲まれており,/* と */ で囲まれた部分にかかれていることはコンパイルに影響ありません.例えば,前回の例題ソースプログラムにコメントを書き込みましょう.エディターで hello.c を開き,次のように変更しましょう.

/* サンプルプログラム hello.c */
/*      u12121212 上山大信   */
#include <stdio.h>

/* main 関数 */
int main()
{
   /* Hello! と画面に表示する */
    printf("Hello!\n");
}

このような短いプログラムではあまりコメントのありがたみは分かりませんが,より長いプログラムでは大変効果的です.プログラムのこの部分ではどのような処理をしているかといった内容をコメントとして書き入れる癖をつけておきましょう.

注意: 全角と半角に気をつけてください.日本語が打てる状態で * や / を書くと全角文字になってしまう場合があります.空白文字も同様に全角の空白文字となってしまうことがあります.こまめに日本語モードと英数モードを切り替えてください.このようなミスもコンパイル時にエラーとなります.例えば * / a B は半角文字ですが,* / a B は全角文字です.つづりも文法もあっているのにエラーが出る場合,まずは全角文字を使っていないか疑いましょう.

なお、最近のC言語では、大抵コメントとして行頭で // が使えます。

// サンプルプログラム hello.c 
//      u12121212 上山大信   
#include <stdio.h>

// main 関数 
int main()
{
   // Hello! と画面に表示する 
   printf("Hello!\n");
}

字下げ

サンプルソースプログラムでは適当に字下げが行われていました.実は,コンパイル時には字下げは全て無視されます(コンパイラーにとっては字下げなど不要).字下げは,人間がソースプログラムを読みやすくするために行うもので,今後,より複雑なプログラムを作成する際には見やすいように字下げをしてください.字下げのスタイルは色々ありますが,今後私が示すであろうサンプルプログラムの字下げを参考にして,自分なりに見やすい字下げを模索してみてください.

上記,コメントと字下げについては,プログラムの読みやすさという意味では特に重要です.

変数

全てのプログラミング言語には変数と呼ばれるものがあります.変数は,データ(数値であったり,文字列であったり)を一時的に保存しておく箱によくたとえられます.コンピュータープログラムは,そのような変数と呼ばれる箱に入ったデータを処理することにより,有用な仕事をします.また,変数を用いることで,より柔軟な処理を行うことができます.

変数には,整数型実数型文字型と数種類ありますが,まずは整数型変数を扱います.整数型変数は,整数値を保存するための箱です(実数値は保存できない).

変数にはそれぞれ符号付型(signed)と符号無し型(unsigned)の二種類がありますが,当面符号付型を用います(負の数も扱いたいので).

C言語における変数の宣言と変数の使用

C言語では,変数を使う場合には関数のはじめの部分で全て宣言しておく必要があります.次に簡単なサンプルソースプログラムを示します.エディターで打ち込み,ファイル名を Part3-1.c として C フォルダーに保存してください.(説明の為に行番号をつけています.エディターにて打ち込む時には行番号は打ち込まないでください.)

 1: #include <stdio.h>
 2:
 3: int main()
 4: {
 5:     int  a, b, c;
 6: 
 7:     a = 5;
 8:     b = 12;
 9:     c = a + b;
10:
11:    printf(" %d\n", c);
12: }

5行目:

これはこれから main 関数の中で使う変数を宣言している部分です.int は Integer の略で,整数型の変数を宣言する場合に使います.その int のあとに a, b, c と列挙されていますが,このようにカンマで区切って列挙することで,一度に整数型変数 a, b, c を宣言することができます.行の最後のセミコロンは文の終わりを示しています.宣言とは,先ほどの変数は箱だという説明にそえば,整数を入れることができる a, b, c とそれぞれ名前のついた3つの箱を用意したことになります.

7行目:

整数型変数 a に整数 5 を代入しています.代入とは,箱の例でいえば,整数を入れることができる箱に整数である 5 という数値を入れることに対応します.行の終わりのセミコロンは文の終わりを示しています(以下同様).

8行目:

同様に整数型変数 b に整数 12 を代入しています.

9行目:

整数型変数 c に a+b の結果(a と b の和)を代入しています.先の7,8行目で a には 5,b には 12がそれぞれ入っているので,c には 5+12 の結果である 17 が入ります.もちろん 17 も整数です(整数同士を足し合わせたのだから当然です). この例からわかることは,変数同士の演算(この場合は足し算)の場合は,その変数の内容(保存されている数値)同士に対し演算が行われ,その演算式は演算結果の値を持つということです.つまりこの例では,c には a+b の演算結果である 17 が代入されます.

11行目:

整数型変数 c の内容を printf 関数を用いて画面に表示します.詳しくは,次の節で説明します.

5行目の宣言は次のように書いても同じことです.ただし,サンプルプログラムのように列挙した方がすっきりしていますね.

    int a;
    int b;
    int c;

また,次のプログラムでもサンプルプログラム同じ結果を得ることができます.

#include <stdio.h>

int main()
{
    printf(" %d\n", 5+12);
}

上記ソースプログラムは,先ほどのサンプルソースプログラムよりもずっと簡単に見えます.なぜわざわざ変数なんてものを使うのでしょうか.それは,今後習う事柄を理解することで明らかになりますので,楽しみにしておいてください.今は変数の定義の仕方と簡単な使い方を覚えてください.

なお,サンプルプログラム Part3-1.c をコンパイル,実行するにはターミナルを開いて,

cd  ~/Documents/C/
cc  Part3-1.c  -o  Part3-1
./Part3-1

とします.はじめの cd work は自分の位置を work フォルダーに移動することを意味していました.

printf 関数を使って変数の内容を画面に表示する

先の例題プログラムにコメントをいれて書き直したものを次に示します.ここでの目標は,整数型変数の内容を画面に表示する場合のprintf 関数の使い方をマスターすることです.

#include <stdio.h>

int main()
{
    /* 整数型の変数 a, b, c を用意する */
    int  a, b, c;
    /* 整数型変数 a に値 5 を代入 */
    a = 5;
    /* 整数型変数 b に値 12 を代入 */
    b = 12;

    /* 整数型変数 c に a+b の結果を代入 */
    c = a+b;
    /* 変数 c の内容を画面に表示 */
    printf("%d\n", c);
}

最後の printf 関数以外は既に説明済みです.

整数値を画面に表示するにはこの例のように

printf("%d\n", c);

とします.\n は前回でてきた改行を示すものでした(前回言い忘れましたが,特殊文字と呼びます).

問題は %d です.printf 関数の中で用いられる %d のことを,変換文字列といいます.%d の d は decimal(10進数)の頭文字の d に由来します.つまり, %d は対応する変数または数値を,10進数整数として表示する働きをもちます.対応する変数または数値とは,今の場合は整数型変数 c ということになります.

複数の数値を表示したい場合は,次のように書くこともできます.

printf("%d %d %d\n", a, b, c);

この場合,%d が3つ並んでいますが,これらはそれぞれ後に続く a, b, c に対応しています.

先の例題プログラムを次のように変更してみましょう.printf 関数のところだけ変更されています.

#include <stdio.h>

int main()
{
    /* 整数型の変数 a, b, c を用意する */
    int  a, b, c;
    /* 整数型変数 a に値 5 を代入 */
    a = 5;
    /* 整数型変数 b に値 12 を代入 */
    b = 12;

    /* 整数型変数 c に a+b の結果を代入 */
    c = a+b;
    /* 変数 a,b,c の内容を画面に表示 */
    printf("a=%d\nb=%d\na+b=%d\n", a, b, c);
}

この場合も,3つの %d があり,それぞれ後ろの a, b, c に対応しています.つまり,変換文字列と, printf 関数の第2引数以降の引数の数は一致しています.

先の例でもありましたが,対応するものは変数である必要はありません.次のような使い方も可能です.

printf("%d\n", 4+5);

この場合,9と表示されます.

代表的な変換文字列を示しておきます.

%o

8進数で出力する

%d

10進数で出力する

%x %X

16進数で出力する.%x は小文字,%Xは大文字で出力

%f %lf

浮動小数点数として出力する (%lf は倍精度浮動小数点時・後述)

%c

文字として出力する

%s

文字列として出力する

このような変換文字列を,変数の型や表示したい様式にあわせて使うことになります.

言葉で説明するとごちゃごちゃしてわかりにくいですが,あれこれ自分で試してみるのが一番良いと思います.次の課題に取り組んでください.

課題1

例題プログラム Part3-1.c を変更して,整数型変数とprintf関数の使い方の練習をせよ.C言語では + の他に

+  加算
-  減算
*  乗算
/  除算
%  剰余 (整数のみ)

が利用できる.

実数型変数

実数型変数は

float  u, v, w;

というように宣言します.float は,浮動小数点数の(floating point number)からきています.また, printf 関数で実数型変数を表示する場合の変換文字列は %f です.以下のプログラムをエディターで打ち込み実行してください.ファイル名は Part3-2.c としてください.

#include <stdio.h>

int main()
{
    float pi, r, s;

    pi = 3.14159;
    r = 2.0;

    s = r*r*pi;

    printf("半径 %f の円の面積は %f です.\n", r, s);
}

このプログラムでは,実数型変数 pi, r, s を用意し,pi には 3.14159 という値を代入し,r には 2.0 という値を代入しています.さらには s に pi*r*r (円の半径を r とした場合の円の面積を求める公式)の計算結果を代入しています.つまり,最後の printf 関数で画面に表示される s の値は,半径 2 の円の面積(の近似値)ということになります.

注意:C言語の実数型(浮動小数点数型)には float (単精度浮動小数点数型)のほかに double (倍精度浮動小数点数型)があります.名前からわかるように,倍精度浮動小数点数型の方が,より高精度に数値を表現することができます(通常単精度浮動小数点型は32bitであって,倍精度浮動小数点型は64bitで表現される).今後,演習のホームページでは実数型としては double を用いるよう統一します(場合によって float を用いることもあります).参考のために,先のサンプルプログラムの倍精度浮動小数点数型を用いたバージョンを以下に示します.(ここでは printf 関数のみ使っているので,実際には printf 関数内の変換文字列は %f, %lf 双方どちらでもよい.後にでてくる scanf 関数の場合には double 型を用いる場合には %lf を用いる必要がある.)

#include <stdio.h>

int main()
{
    double pi, r, s;

    pi = 3.14159;
    r = 2.0;

    s = r*r*pi;

    printf("半径 %lf の円の面積は %lf です.\n", r, s);
}

課題2

サンプルプログラム Part3-2.c を変更して,半径 3.2 の円の面積(の近似値)を求めよ.

実数型変数を使うことで,円の面積(の近似値)を求めることができました.しかし,これでは違う半径の円の面積を求めたい場合,課題2のようにいちいちエディターでソースプログラムファイルを変更して,コンパイルし実行せねばなりません.半径はキーボードで我々が入力したいものです.次節では,標準関数である scanf 関数を使って,キーボードからの数値データの入力を実現します.

scanf 関数

キーボードから数値データを入力するには scanf 関数という標準関数を用います.printf 関数は出力を行う関数でしたが,scanf 関数は入力を行う関数です.

scanf 関数による整数値の入力

scanf 関数を用いたもっとも簡単なプログラムは次のようなものになります.ファイル名を Part3-3.c として,エディターで打ち込んでください.

1: #include <stdio.h>
2: 
3: int main()
4: {
5:     int i;
6: 
7:     scanf("%d", &i);
8:     printf("%d\n", i);
9: }

このプログラムは,キーボードから入力された整数値データをそのまま画面に表示します.このプログラムの中で,7行目の scanf 関数がキーボードからのデータ入力を行います.

scanf("%d", &i);

となっていますが,前半のダブルクォーテーションで囲まれた文字列は,printf 関数と同様の変換文字列です.ただし,printf 関数のように通常の文字列と変換文字列が両方書くことはできず,scanf 関数では変換文字列のみ書くことができますこのサンプルプログラムでは,整数型変数 i に値を入力するので,整数型変数の変換文字列である %d がかかれています.そのあとには コンマ に続いて &i とかかれています.scanf 関数では,変換文字列に続いて,入力されたデータを格納する変数名がきますが,変数名の頭に & をつける必要があります.& をつけねばならない理由はもちろんあるのですが,ここでは scanf 関数では変数の頭に必ず & をつけると覚えてください.

scanf 関数による実数値の入力

scanf 関数を用いて,実数値を入力し,それをそのまま出力するサンプルプログラムは次のようになります.ファイル名を Part3-4.c としてください(Part3-3.c とほとんど同じなので,Part3-3.c を変更し,別名保存しましょう).

1: #include <stdio.h>
2: 
3: int main()
4: {
5:     double a;
6: 
7:     scanf("%lf", &a);
8:     printf("%lf\n", a);
9: }

入力促進メッセージの出力

先の2つのプログラムでは,「・・を入力してください」といったメッセージは全く画面にでませんでした.これでは,プログラムを使う人にはあまりに不親切です.次のように Part3-4.c を次のように変更しましょう.

 1: #include <stdio.h>
 2: 
 3: int main()
 4: {
 5:     double a;
 6: 
 7:     printf("実数値を入力してください: ");
 8:     scanf("%lf", &a);
 9:     printf("入力された実数値は %lf です.\n", a);
10: }

7行目に printf 文が加わりました(9行目も変更されています).このように,入力促進メッセージは,scanf 関数に先立って printf 関数で表示する必要があります.次のように書きたくなる人もいるかもしれませんが,このような書き方はできません

間違った例

scanf("実数値を入力してください: %lf", &a);

円の面積を求めるプログラム(改良版)

では,scanf 関数を使って,先にでてきた円の面積を求めるプログラムを改良しましょう.

次のサンプルプログラムを Part3-5.c としてエディターで打ち込んでください(行番号は無視してください).これまでの知識で十分理解できるはずです.

 1: #include <stdio.h>
 2:
 3: int main()
 4: {
 5:     double pi, r, s;
 6: 
 7:     pi = 3.14159;
 8:    
 9:     printf("円の半径を入力してください:");
10:     scanf("%lf", &r);
11:
12:     s = r*r*pi;
13:
14:     printf("半径 %lf の円の面積は %lf です.\n", r, s);
15: }

このサンプルプログラムは,先ほどのサンプルプログラム Part3-2.c を少しだけ変更した内容となっています.先のプログラムで ,

r = 2.0;

としていた部分が,printf 関数と scanf 関数に置き換わっています.ターミナルでコンパイルし,実行すると,

円の半径を入力してください:

と表示され,その状態でとまります.そこで,メッセージどおりに,面積を求めたい円の半径を入力します.例えば, 3.2 と打ち込んで,Enter キーをおしてみましょう.半径 3.2 の円の面積が求まったでしょうか?

この節でわかったことをまとめると,

printf 関数と scanf 関数を組み合わせて用いれば,メッセージを表示して,キーボードから数値を変数に読み込むことができる

ということになります.

これまでの内容の復習として次の課題に取り組んでください.

課題3

Part3-5.c を float をつかうものに書き換えよ.

課題4

円の半径を入力すると,円の面積および円の円周を計算して両方を画面に表示するプログラムを作成せよ.

課題5

下記のサンプルプログラムを ,プログラムの利用者が自由に整数値 a, b を入力できるように scanf 関数をつかったものに変更せよ.さらには,足し算だけでなく,その他 a-b, a*b, a/b, a%b 全ての結果を表示するようにせよ.

  1. b を 0 としてみよ.その場合 0 での割り算が生じ不都合がでる.この問題を回避するには来週以降習う,条件分岐が必要となる.
  2. a = 1, b = 2 としたとき a/b の結果は 0 となる.やってみよ.
 1: #include <stdio.h>
 2:
 3: int main()
 4: {
 5:     int  a, b, c;
 6: 
 7:     a = 5;
 8:     b = 12;
 9:     c = a + b;
10:
11:    printf(" %d\n", c);
12: }

課題6

課題5の変数を全て実数型(double)に変更したプログラムを作成せよ.a = 1.0, b = 2.0 としたとき a/b の結果はどうなるか?

課題7

scanf 関数と printf 関数を用いて,何か他のプログラムを作成せよ.

課題8

これまで得た知識を用いて,何か実用的なプログラムを作成せよ.例えば,以下のようなもの.

  • 燃費計算プログラム
  • 消費税計算プログラム
  • 肥満度判定プログラム
  • 秒速・時速変換プログラム
  • 通貨単位変換プログラム
  • 平均速度を求めるプログラム
  • 等等

作成したら,(現状の知識では無理であるが)どのような機能を付け加える必要があり,そのためにはどういった処理が必要か等考えよ.

Part3で学んだ事

  • フォルダーを作成し,ファイルをフォルダーに移動しました
  • 変数(整数型と実数型)を使えるようになりました
  • 変数を使った足し算を行いました
  • 変数を使ったいろいろな計算をしました
  • 変数の内容を printf 関数を用いて画面に表示できるようになりました
  • scanf 関数を使って,数値データをキーボードから入力できるようになりました
  • scanf 関数では,変数名の頭に & をつける必要がありました