変数の定義

変数

変数はデータを名前で呼ぶための仕組み。

データを入れる箱に名前をつけておくというふうに考えるといいでしょう。

以下の課題は Hello.c と同様に実習します。

  1. エディタでプログラムを作り、指定されたファイル名(たとえばk0201.c)で保存します
  2. コンパイルします (たとえば ~/c$ gcc k0201.c -o k0201)
  3. 実行して結果を確認します。(たとえば ~/c$ ./k0201)
  4. コンパイルに失敗したり、実行結果が思わしくなければプログラムを修正して繰り返します。

課題2-1 変数の宣言・代入・参照

変数を使ったプログラムです。後に説明があります。

プログラム名 k0201.c

 1: /* 変数を使う: k0201.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a;
 7:     int b;
 8:     int c;
 9:     a = 13;
10:     b = 25;
11:     c = a + b;
12:     printf( "%d\n",c );
13:
14:     return 0;
15: }

行頭の番号とコロン(:)は解説のためにつけてあるものなので、プログラムには入力しません。

文字はここからエディタにコピーできますが、不要な改行やスペースが一緒にコピーされるとコンパイルできなくなることがあります。コピー後に不要なものを削除したり訂正する必要がないか確認しましょう。

重要なところはコピーせず自分で入力したほうが記憶に残ります。

プログラム解説 k0201.c

1:
コメントです。この1行は省略してもよいし、別のコメントを書いても良い。
6:int a; 変数の宣言
int は integer の略で「整数」です。int a;a という整数を入れる変数を作ります。最後の ; は Cの文の終わりです。日本語の「。」に相当します。
7:
続いて b という整数を入れる変数を作ります。
8:
続いて c という整数を入れる変数を作ります。
a, b, c, などを変数名といいますが、英字で始まり英数字が続く文字列にします。言語によって英数字以外の文字(たとえば _ や - や 日本の文字など)が使えるシステムもありますが、英数字が無難です。
9:a = 13; 変数へ値の代入
a = 13; は変数 a に 13 という整数値を代入することを表します。
以降 a を足すことは 13 を足すこと、a を引くことは 13 を引くことになります。
10:
b = 25; は変数 b に 25 という整数値を代入することを表します。
b = 25;b と 25 が等しいという意味ではありません。= の右側の値を左側に代入します。
= の左右にスペースを空けるかどうかは趣味の問題です。b=25;とくっつけて書いても問題ありません。; の前後も同様です。
11:c = a + b; 変数の値の参照(使う)
a + b つまり、13+25 を計算して、結果を c に代入します。
c = a + b;ca + b が等しいという意味ではありません。
12:printf( "%d\n",c ) 書式のあるprintf
printf の新しい使い方です。( )の中にコンマで区切られて "%d\n",c となっています。これは"%d\n"という書式で c の内容を表示しなさいということです。
"%d\n"%dは十進数(整数)として書く指定です。cは38ですからそのまま38と表示されます。
\nは最後に改行するということです。

実行結果は

~/c$ ./k0201 
38

課題2-2 変数の宣言はまとめてできる

変数の宣言をまとめることができます。k0201.c に比べてint a,b,c;の部分が異なるだけです。6,7,8行目が6行目1行にまとめられています。

プログラム名 k0202.c

 1: /* 変数の宣言をまとめることができる: k0202.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a,b,c;
 9:     a = 13;
10:     b = 25;
11:     c = a + b;
12:     printf( "%d\n",c );
13:
14:     return 0;
15: }

実行結果は同じです。

課題2-3 宣言と代入をまとめてできる

変数の宣言と代入をまとめることができます。k0201.c に比べてこの色の部分が異なるだけです。k0201.c の 9,10,11行目が6,7,8行目にまとめられています。

プログラム名 k0203.c

 1: /* 変数の宣言と代入をまとめることができる: k0203.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 13;
 7:     int b = 25;
 8:     int c = a + b;
12:     printf( "%d\n",c );
13:
14:     return 0;
15: }

プログラム解説 k0203.c

6: 宣言と代入のまとめ
int a;a = 13; をまとめて int a = 13;と書いてもよいということです。
7:
int b;b = 25; をまとめて int b = 13;と書いてもよいということです。
8:
int c;c = a + b; をまとめて int c = a + b;と書いてもよいということです。

実行結果は同じです。

課題2-4 printfの書式

printf の書式について。k0203.c に比べてこの色の部分が異なるだけです。

プログラム名 k0204.c

 1: /* printfの書式: k0204.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 13;
 7:     int b = 25;
 8:     int c = a + b;
12:     printf( "%d + %d = %d\n",a,b,c );
13:
14:     return 0;
15: }

プログラム解説 k0204.c

12: 複数の%d
3つの %d が十進数を書く場所が3つあることを示しています。
それに3つの変数 a,b,c がそれぞれ対応しています。
%d 以外の文字はそのまま表示されます。もちろん \n は改行になります。

実行結果は

~/c$ ./k0204
13 + 25 = 38

課題2-5 printfの中で計算させる

k0204.c に比べて 8: がなくなって、この色の部分が異なるだけです。

プログラム名 k0205.c

 1: /* printfの中で計算させる: k0205.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 13;
 7:     int b = 25;
12:     printf( "%d + %d = %d\n",a,b,a+b );
13:
14:     return 0;
15: }

プログラム解説 k0205.c

12:printfの中で足し算
c にあらかじめ a+b の結果を代入する代わりに、printf の中で a+b を計算させることができます。
今度は a+b の結果が3番目の %d に対応します。

実行結果は同じです。

~/c$ ./k0205
13 + 25 = 38

課題2-6 別の書式を試す

k0205.c に比べて、この色の部分が異なるだけです。

プログラム名 k0206.c

 1: /* 別の書式を試す: k0206.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 13;
 7:     int b = 25;
12:     printf( "%d と %d を掛けると %d です。\n",a,b,a*b );
13:
14:     return 0;
15: }

プログラム解説 k0206.c

12:%d 以外の文字ははそのまま表示される / 掛け算の記号は *(星)
+= の代わりに文章にしてみました。%d 以外の部分はそのまま表示されるのです。
今度は a*b と掛け算にしました。掛け算の記号 × が半角にないので * を使います。

実行結果は

~/c$ ./k0206
13 と 25 を掛けると 325 です。

C言語の四則演算子(加減乗除)

全部半角記号です。

演算 足す 引く 掛ける 割る
C言語の記号 + - * /

課題2-7 整数の割り算は整数になる

k0206.c に比べて、この色の部分が異なるだけです。

プログラム名 k0207.c

 1: /* 整数の割り算は整数: k0207.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 20;
 7:     int b = 3;
12:     printf( "%d を %d で割ると %d になります。\n",a,b,a/b );
13:
14:     return 0;
15: }

プログラム解説 k0207.c

6:
割り算結果が割り切れないように数値を変えました。
7:
割り算結果が割り切れないように数値を変えました。
12:掛け算を割り算に
掛け算を割り算にしたので説明文も変えました。割り算の記号は /(スラッシュ)です。
整数の割り算は少数以下は切り捨てになります。

実行結果は

~/c$ ./k0207 
20 を 3 で割ると 6 になります。

課題2-8 " + " と " * " の優先順

k0207.c に比べて、この色の部分が異なるだけです。

プログラム名 k0208.c

 1: /* 優先順: k0208.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     int a = 20;
 7:     int b = 3;
 8:     int c = 5;
 9:     int s1 = a + b * c;
10:     int s2 = (a + b) * c;
11:     printf( "%d + %d * %d = %d \n",a,b,c,s1 );
12:     printf( "(%d + %d) * %d = %d \n",a,b,c,s2 );
14:     return 0;
15: }

プログラム解説 k0208.c

8:
変数を増やしました。
9:
a + b * c の計算結果を s1 という変数に代入します。
変数名は英字で始まる英数字からなる文字列であれば自分で決められます。
10:
(a + b) * c の計算結果を s2 という変数に代入します。
変数名は英字で始まる英数字からなる文字列であれば自分で決められます。
11:
s1 の値を a + b * c の式と一緒に表示します。
12:
s2 の値を (a + b) * c の式と一緒に表示します。

実行結果は

~/c$ ./k0208
20 + 3 * 5 = 35 
(20 + 3) * 5 = 115 

括弧がなければ、足し算より掛け算を先に計算することがわかりました。

* や / は + や - より先に行います。優先がなければ左から順に計算します。

変数の型(char, int, float, double)

C言語で使われる変数の型のうち主要なものの説明です。

変数の型意味バイト数
char1バイトの文字11文字の文字を格納するのに用いられる(日本語の文字は入れられない)。
int整数4バイト数はコンパイラに依存する
(4バイトでは -2147483648 ~ 2147483647 まで表現できる)
float浮動小数点実数4少数以下をもつ数を代入できる変数
double倍長浮動小数点実数8floatをより精度・範囲を広げたもの

この他に、short int(short), long int(long), unsignedのついたもの, long doubleなどがあります。

課題2-9 float を使ってみる

k0208.c に比べて、この色の部分が異なるだけです。

プログラム名 k0209.c

 1: /* float: k0209.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     float a = 20;
 7:     float b = 3;
 8:     float c = 5;
 9:     float s1 = a + b * c;
10:     float s2 = a / b;
11:     printf( "%f + %f * %f = %f \n",a,b,c,s1 );
12:     printf( "%f / %f = %f \n",a,b,s2 );
14:     return 0;
15: }

プログラム解説 k0209.c

6-9: floatとして宣言
int が float になりました。変数名は同じですがこのプログラムでは int でなく float と宣言しています。
10: floatで割り算
k0207.c では int だったので a / b 答えが切り捨てられて整数になりましたが、float ではそうならない(実数として計算される)ことを確かめます。
正確には a,b が float なので計算で切り捨てされず、s2 も float なので代入でも切り捨てられず、printfの指定も少数を表現するものなのでこうなります。
11: %f 書式指定文字
%dは(decimal)十進の整数を表示することを示します。今回は少数点以下の数を扱うので%fを使います。
同じ20でもint型の変数に入れた場合とfloatの変数に入れた場合ではメモリ上のデータの形式が異なります。%dはそれを整数として、%fは浮動小数点数として読み取るようにとの指定です。floatの変数の値を%dで表示すると間違った表示になります。
12:
%d%fに変更しました。また、s2 の計算が割り算になったのでそれに合わせて書き換えました。

実行結果は

~/c$ ./k0209
20.000000 + 3.000000 * 5.000000 = 35.000000 
20.000000 / 3.000000 = 6.666667 

%fとすべきところを%dのままにした場合の実行結果は

~/c$ ./k0209
0 + 1077149696 * 0 = 1074266112 
0 / 1077149696 = 0 

OSの種類、コンパイラの種類により結果は違いますが、変数の型とprintfの書式指定文字(%d,%fなど)が正しく対応しているか確認しましょう。

書式指定文字( %d, %f, %g )

文字 対応する変数の型 説明 使用例
%c char 1文字を出力する "%c"
%s char * 文字列を出力する "%4s", "%-8s"
%d int 整数を10進で出力する "%4d","%-4d"
%x int 整数を16進で出力する "%2x", "%4x"
%f float 実数を出力する "%8.2f"
%e float 実数を指数表示で出力する "%8.3e"
%g float 実数を最適な形式で出力する "%g"
%lf double 倍精度実数を出力する "%12.3lf"

単に指定文字だけ書いた時は必要な幅が確保されて表示されます。

% と d,f などの間に整数を書くと表示幅をそれに合わせようとします。

f,e などではさらに小数点と整数を書き加えて小数点以下の桁数を指定できます。

課題2-10 %g を使ってみる

k0209.c に比べて、この色の部分が異なるだけです。

プログラム名 k0210.c

 1: /* %g: k0210.c */
 2: #include <stdio.h>
 3:
 4: int main()
 5: {
 6:     float a = 20;
 7:     float b = 3;
 8:     float c = 5;
 9:     float s1 = a + b * c;
10:     float s2 = a / b;
11:     printf( "%g + %g * %g = %g \n",a,b,c,s1 );
12:     printf( "%g / %g = %g \n",a,b,s2 );
14:     return 0;
15: }

プログラム解説 k0210.c

11: %g 書式指定文字
%gは余計な小数点以下の0を省略するなど見やすい形に整えてくれます。本来は科学技術計算で使用する%eと%fのうち最適なものを選択させるために作られました。

実行結果は

~/c$ ./k0210
20 + 3 * 5 = 35 
20 / 3 = 6.66667 
聖愛中学高等学校
http://www.seiai.ed.jp/
Nov. 2011