04 変数と定数

プログラミングでは「変数」の意味を正しく理解することが重要です。ここでの「意味」には,「型」や「有効範囲」などの概念も含みます。

変数と代入

パソコンの黎明期,アマチュアが使うプログラミング言語がBASICだったころ,「変数」はよく「箱」にたとえられました。「a」という名前の箱を用意して,その中に具体的は数をいれる,というわけです。箱に入った数は入れ替えることもできるわけです。これを「代入」といいます。どちらかというと,数学の変数をイメージした方がよいでしょう。「x=2 で xに2を代入する」という具合です。ここで「=」は「等しい」ではなく,「にする」という意味です。

変数の型

コンピュータは,メモリにデータを記憶してさまざまな処理をします。このとき,データがどんな数か,あるいは文字かによって記憶領域のサイズが変わります。小数は整数より多くの領域を要しますが,それでも32ビットか64ビットという固定した大きさの領域があれば済みます。文字列の場合はその長さによって領域を変化させなければなりません。

そこで,「この変数ではどんなデータを扱うか」が管理上大切な事柄になります。これを「型」といいます。

Cindyscriptで扱える「型」には,「数」「文字」「リスト」「幾何要素」「ブール値」があります。

数は,整数,実数,複素数のいずれかです。

リストは,数や文字などを集めたもので,数のリストはベクトル,数のリストのリストは行列として扱えます。

ブール値は真:true,偽:false のいずれかです。

多くのプログラミング言語では,この「型」を最初に宣言して,その変数のための記憶領域を用意します。したがって,「整数」と宣言した変数に文字を代入することはできません。

しかし,Cindyscriptではこの宣言は不要です。必要になったときに使えば,自動的に使ったときの型になります。しかも,整数として使っていた変数に文字を代入することもできます。

とはいえ,この「型」の考え方はプログラミングをする上では大切なので,Cindyscriptでもまったく避けて通ることはできません。

たとえば,実数と実数はたし算ができますが,実数と文字列のたし算はできません。いま使っている変数にどんな型のデータが代入されているかは常に知っている必要があるわけです。

定数

円周率は決まった値です。このような決まった値を「定数」と呼び,プログラミング言語ではそのための名前が用意されています。

Cindyscriptでは,円周率を表す pi と,虚数単位を表す i があらかじめ用意された定数です。この2つに何か値を代入することもできますが,するとそれ以降は pi や i でこれらを表すことができなくなりますので,やめた方がよいでしょう。特に,i は,他の言語では繰り返し用の変数としてよく使われますがCindyscriptでは別の文字を使う方がよいでしょう。ただし,虚数を扱わないのであれば使っても構いません。

変数の有効範囲

どのプログラミング言語にも,変数に「局所変数」と「大域的変数(グローバル変数)」の概念があります。局所変数は,その名の通り,局所的に有効な変数,グローバル変数はプログラム全体で有効な変数です。

<例> つぎのプログラムは点を5個表示します。

a=2;

repeat(5,s,

draw([a,s]);

);

a=2 となっているので,点は(2,1),(2,2),(2,3),(2,4),(2,5) の5つです。

ここで a=3 とすると,点は(3,1),(3,2),(3,3),(3,4),(3,5) に変わります。

すなわち,変数 a は,このプログラム全体に有効になっています。

一方,変数s は,repeat()関数の働きによって1から5まで変化しますが,これはrepeat() の中だけで有効です。

それを確かめるために,

draw([a,s+1]);

をこのあとに追加してみましょう。点は5個のままです。

変数 s の値は repeat() の外では無効になってしまい,定義されていないものとして扱われるわけです。

プログラムが大きくなった場合は,変数の有効範囲に気をつけなければいけない場合が出てきます。今使おうとしている変数の値がどこかで書き換えられているかもしれないからです。「どこか」というのは,ユーザー定義関数の中です。

たとえば,次のようなプログラムを作ったとします。

divide(a,b):=(

q=floor(a/b);

r=mod(a,b);

[q,r];

);

r=3;

a=8;

n=divide(13,3);

c=n_1;

drawcircle([c,0],r);

何をするかというと,aをbで割った商と余りをリストにして返す関数 divide(a,b) を用意して,今は,そのうち商だけを利用して,x座標がその商であるような点を中心とする半径3(r=3)の円を描こうとしているのです。

7行目で r=3 として,これを drawcircle([c,0],r); の半径で使ったつもりなのですが,この r は定義したあとで使った n=divide(13,3) を計算するときに関数の中で使われているので,3ではなくなっているのです。そのことに気がつかないと,半径3の円が描かれないのでおかしなことになってしまいます。

ユーザー定義関数の中で使っている変数は,グローバル変数だと思った方がよいでしょう。

上のエラーを防ぐには,ユーザー定義関数の中で使う変数を regional() で局所変数として定義します。

divide(a,b):=(

regional(q,r);

q=floor(a/b);

r=mod(a,b);

[q,r];

);

とすると,こんどは予定通りの動作をします。

変数に使える文字

変数にはアルファベット,数字,漢字が使えます。ただし,次のような制限があります。

・アルファベットは大文字と小文字を区別します。Xとxは別の変数です。

・数字は最初には使えません。a1 はよいですが 1a はエラーになります。

・作図ツールで描いた点や線には,A,B,・・ a,b,・・などの名前がつきます。

この名前はその要素を表わし,たとえば点Aの座標を A.xy として取得することができます。

これらの文字は変数として使えますが,何か値を代入するとそれ以降は点を表せなくなります。

幾何の要素をスクリプトで制御するときは,これらを変数として使わないようにしましょう。

前述のように,変数には局所変数とグローバル変数があります。大きなプログラムでは意識する必要が出てくるので,そのような場合は,局所変数は小文字で始め,グローバル変数は大文字で始めるようにして区別するとよいでしょう。