変数
プログラムに計算させてみる
例題:次の図を描くプログラムをHandyGraphicを使って作成せよ(赤色の座標値は描かなくてよい)。ただし、ウィンドウの大きさは幅600x高さ400、長方形の左下と右上の座標は図に記したとおりである。
HandyGraphicではウィンドウの左下が原点(0, 0)であることに注意。
長方形を描くにはHgBox関数を使えばよいが、HgBox関数の引数は次のようになっている:
int HgBox(double x, double y, double w, double h)
長方形を描く
引数: x,y:左下隅の座標 w,h:幅と高さ
そこで、幅と高さを計算する必要があるが、これらを人間が手で計算するのも面倒臭い。コンピュータは計算が得意なのだからコンピュータに計算させればよいではないか。
プログラム中、数値を書くべきところには計算式を書くこともできる。計算式には四則演算を使える。計算の優先順位を指定するための()(括弧)も使うことができる。詳しくは教科書2.3.2節を参照。
この例の場合、次のようにして長方形を描くことができる。
HgBox(100, 100, 450 - 100, 270 - 100);
,の後や演算子の前後にスペースを入れるか入れないかは自由である。自分が読みやすいと思う方法で統一するとよい。
練習:このプログラムを完成させよ。
変数:数値を記憶する
例題:次の図を描くプログラムをHandyGraphicを使って作成せよ(赤色の矢印および比率を表す数字は描かなくてよい)。ただし、ウィンドウの大きさは幅600x高さ400、2つの正方形の大きさは114、横方向の端と正方形の間の長さはそれぞれ1:2:3の比率、縦方向の端と正方形の間の長さは1:2の比率である。図形描画に必要な座標値はプログラム中で計算させること。
先ほどと同様に、それぞれの正方形の左下の座標の計算式を考えればよいのだが、今回の計算は少々複雑である。
練習:計算手順を書き出してみよう。
縦方向と横方向はそれぞれ別々に計算すればよい。 縦方向は、ウィンドウの高さから正方形の大きさを引いた残りを半分に(5/13訂正)2/3にすればよい。
横方向に関しては、例えば次のような計算手順が考えられる:
- 横方向の余白部分の和を計算する。
- 1で求めた余白部分を1:2:3の比率で配分したときに、1に相当する余白量を計算する。左側の正方形の左下隅のx座標はこの余白量となる。
- 2で求めた余白量に正方形の大きさを加え、さらに2で求めた余白量の2倍を足した値が右側の正方形の左下隅のx座標になる。
これを数式で表してみよう。1.や2.の計算結果は次の計算で使うことになるので、変数を使って表せばよい。例えば1の値をd、2の値をg、3の値をxとすると、次のような式になる:
- d = 600 - 114 * 2
- g = d / 6
- x = g + 114 + g * 2 (あるいは g * 3 + 114)
プログラムでも同じように変数を使うことができる。変数とは、何かの値(計算結果)を覚えておく箱、とイメージすればよい。変数は複数使うことができ、それぞれ名前を付けて区別する(ここまでは数学と同じ)。
Cのプログラムで変数を使う際には、どの名前の変数を使うか、その変数はどのような種類の値を扱うのか、を予め宣言する必要がある。例えば次のように書く:
/***** calcGaps.c draw two rectangles Mitsuru Minakuchi *****/ #include <stdio.h> #include <stdlib.h> #include <handy.h> int main() { int xDist; // 横方向の余白量 int xGap; // 横方向の余白を1:2:3で配分したときの1つ分 int x; // 2つめの正方形のx座標 }
変数の宣言は一般的に、次のような書式になる(教科書2.2.3〜2.3.1節参照):
(変数のデータ型) 変数名;
int(integerの頭3文字)は整数のデータ型を表す。データ型については後述する。
変数の宣言は一般的に関数の中の最初の位置に固めて書く。
関数の外に書く方法や、関数の途中に書く方法もあるが、意味が少々難しくなる。現時点では関数の最初に書く、としておく。
変数名はアルファベット、数字、アンダースコア_の組み合わせの任意の名前を付けることができる。大文字と小文字は区別される。ただし、最初の1文字目は数字はダメ。また、C言語で既に使われている名前(予約語と呼ぶ)も使用不可。既に宣言した変数が有効な範囲内で、同じ変数名を持つ変数を再度宣言することもできない。これらのダメな場合はコンパイラーがエラーを報告するので、容易に間違いに気付くはずである。
変数名は任意であるので、aとかbでも良いような気がするが、一般的には「変数の意味が端的に分かる単語」を使うべきである。複雑なプログラムになるとどのような計算をやっているのかわからなくなるし、プログラムを書いた本人ですら驚くほどに忘れてしまうものであるから。上記の例では、dの代わりにdistance(距離)のdist、gの代わりにgap(ギャップ、隙間)とし、さらに横方向=x軸であるのでxをつけてxDist、xGapとしている。英語でなくてもローマ字でもよいが、変な名前だとかえって読みにくくなるので注意。 また、どのような値の変数なのか、意味をコメントで書いておくことが望ましい。詳しくは教科書2.2.3節を参照。
練習:xについてはどのような名前がより適しているだろうか?
一部、例外的にアルファベット1文字でも構わない場合がある。繰り返しの回で説明する。また、xのようにx座標であることを明確に表しているのであれば、それも構わないと思う。
複数の単語からなる名前を付ける場合、最初は小文字で始め、2番目以降の単語はそれぞれの単語の先頭を大文字にする書き方(キャメルケースと呼ぶ)が現在では主流である。Cでは_を使って、x_distやx_gapのように書く書き方も依然として多いようである。大文字で始まる名前はCでは使われることもあるが、今後のために使わないようにすることをお薦めする。
練習:教科書演習問題2.1の4
変数を宣言したら、変数に値を設定したり、変数の値を使って計算する。数学の式と同じように書けばよい。Cでは=(イコール)は代入演算子と呼ばれ、=の右辺に書かれた値(計算式の計算結果)を、=の左辺に書かれた変数の値とする(代入する)ことを意味する。このような=を使った式を代入式と呼ぶ。プログラムでは1行の最後に;(セミコロン)を付けるのを忘れずに。
Cの=は数学のように左辺と右辺が等しいことを表すのではない点に注意。詳しくは追々説明していく。
/***** calcGaps.c draw two rectangles Mitsuru Minakuchi *****/ #include <stdio.h> #include <stdlib.h> #include <handy.h> int main() { int xDist; // x方向の余白量 int xGap; // x方向の余白を1:2:3で配分したときの1つ分 int x; // 2つめの正方形のx座標 xDist = 600 - 114 * 2; xGap = xDist / 6; x = xGap + 114 + xGap * 2; }
練習:縦方向の座標値(正方形の左下隅のy座標)を変数を使って計算するコードを追加せよ。
必要な座標が計算できたら、後はそれらの値を使って図形を描くコードを追加すればよい。
課題:図形を描くコードを追加してプログラムを完成させよ。
プログラム中、114という数字が何度も出てきてあまり美しくないと感じるかもしれない。114という値を変数に格納して名前を付けておき、それを式に書く方法もある。あるいは、値が決まっていて変化しない定数に名前を付けて定義する方法がある。これらについては追々説明していく。
データ型
コンピュータの内部では2進数で計算しているが人間は10進数を使っている。そこでプログラム中に書かれた値をどのように解釈するか、どれくらいのデータ量(2進数の桁数)で値を表すか、などといったことを決めておかなければならない。
Cでは値や変数をどのように扱うかをプログラムを書く段階で決めておく。
「Cでは」とわざわざ書いているのは、他のプログラミング言語には予め決める必要の無いものもあるからである。Cのようなプログラムの段階で決めておくことを「静的型付け」と呼ぶ。対して、実行時に決めることを「動的型付け」と呼ぶ。
Cプログラムで扱う基本的なデータ型としては次のものが挙げられる(教科書2.2.1〜2.2.2節参照):
整数 ..., -2, -1, 0, 1, 2, ...
プログラム中では数字をそのまま書けばよい(10進数の場合)
Lを最後に付けるとlong型であることを表す(long型は後述)
他に、8進数や16進数表記もあるが今回は省略。
実数 1.2345, 6.02×10^23
プログラム中では小数点を使って書く。10^nの部分は6.02e23のように表記する。10と書くと整数、10.0と書くと実数になることに注意。
Fを最後に付けるとfloat型であることを表す(float型は後述)
文字 a, b, c, ...
プログラム中では'a'のように'(シングルクォーテーションマーク)で文字を囲って書く。
文字列の場合"(ダブルクォーテーションマーク)で囲むのとは異なる点に注意。
これらをどれだけのデータ量(バイト数)で表現するか、で幾つかのバリエーションがある:
整数型
short型:2バイトで表現
long型:4バイトで表現
int型:コンパイラによってshortまたはlongのどちらか(現在はlongが主流)
実数型
float型:4バイトで表現
double型:8バイトで表現
文字型
char型:1バイトで表現
注:C言語では1byteの文字(いわゆる半角英数字)を対象とする。文字列、および日本語などの文字(マルチバイト文字、いわゆる全角文字)は複数の文字型の集合(配列)として扱われる。
他にもより多くのデータ量で表現する、long long int型やlong double型もあるが、通常のプログラムでは使うことはないだろう。
整数型と文字型はunsignedを付けて負の値を扱わないことを宣言することができる。例えばunsigned int、unsigned charなど。char型は1バイトの整数表現と考えればよい。
本演習では主に整数型(int型)のみを扱うことにする。
通常、int型はlong型と同じであるので表現可能な値の範囲も広く、 普通のプログラムでは特に気にすることはないが、特に巨大な数値を扱う場合(指数的に値が増加するような計算など)は注意が必要である。この例については後日紹介しよう。
本日の課題
課題1:次の図を描くプログラムrectAndCircle.cをHandyGraphicを使って作成せよ。ウィンドウの大きさは幅600x高さ400、青い塗りつぶしの正方形の上に黄色い塗りつぶしの円が内接している。円の中心はウィンドウの中心にあり、円の直径は300とする。図形描画に必要な座標値はプログラム中で計算させること(手計算はダメ)。変数は使ってもよいし、使わなくてもよい。
課題2:次の図を描くプログラムcalcCircles.cをHandyGraphicを使って作成せよ。ウィンドウの大きさは幅400x高さ400である。3つの円はお互いに接している。外側の一番大きな円の中心座標は(240, 210)、半径は120である。内側の円2つの直径は2:1となっており、中心のy座標はいずれも外側の円と同じである。図形描画に必要な座標値は変数を使ってプログラム中で計算させること(手計算はダメ)。
提出期限:6/2の授業開始時まで(13:15)