2-4.計算をさせて記憶させる

計算(演算)結果を記憶させてみましょうか。


変数

2-3にて演算を行い、その結果を表示する方法を説明しました。さて、単純な「計算」をさせてそれを表示させるなら、よっぽど電卓で計算してそのまま計算した結果を書き込んだ方が実行速度は速くなります。たったあれぐらいではほんの数ミリ秒程度でしょうが。というわけで、今度は演算結果を記憶させ、またその結果同士をまた記憶させてみます。

計算式については前でやりました。記憶させるには、命令ではなくまた違う書き方をします。


    a = 1 + 2

こうすると、a1 + 2の演算結果、つまり3が入ります。このaとは一体何かというと、変数と言います。

変数は、良く“入れ物(箱)”に例えられます。つまり、データを入れる入れ物、ということです。

この変数にデータ(もの)を入れることを代入と言います。代入を行うには、変数の後に"="と書いて、その後に代入する値を書きます。一応これは代入命令とされています。

    variable = value(or expression)

variable : 変数
value(or expression) : 値もしくは式

つまり、最初の例に出したコードは『aという変数に1 + 2の結果を代入せよ』と書いてあるわけです。

この変数には好きな名前を付けることが出来ます(最大半角59文字)。名前はアルファベットで始まらなければいけません(実は日本語を使えるのですが、日本語を使えるというのはどうやらバグらしいので、アルファベットだけにしておくべきです)。

変数の表示

また、変数の中身を表示することも可能です。mesの後に、文字列の代わりに変数を与えればオーケーです。また、文字列と変数を組み合わせることも可能です。その時は"strings" + variableという形で記述します。例を出すとこんな感じです。


    mes a    ;単純にaの中身が表示される。
    mes "aの値 = " + a    ;最初に"aの値 = "という文字が表示される。

これでaの値を表示できます。ここでaに3が代入してあれば3と表示され、次の行にはaの値 = 3と表示されるわけです。

変数の特徴

変数の特徴として、1つの変数に記憶できるのは、1つの値だけであることを覚えておいてください。


    a = 5   ;aに5を代入
    mes a
    a = 10  ;そして、10を記憶させると……。
    mes a

このコードを実行してみると、最初5が表示され、次に10が表示されるはずです。これは、3行目でaに10を代入したため、元から記憶させていた5が消されてしまったからです。

変数と文字列

変数には数値だけでなく、文字列も記憶できます。代入するものを数値から文字列に変えるだけです。また、数字と文字列を組み合わせることも出来ます。これは変数を表示させる時と全く同じ方法です。


	a = "string"	;"string"を代入
	mes a			;aを表示
	a = "string"+123;組み合わせる
	mes a			;aを表示

画面にはstringと表示され、次の行にstring123と表示されるはずです。この時、既に'123'は数値ではなく、文字列の一部として扱われています。さらに、文字列同士の加算(というか結合)も可能です。


	a = "String" + "Variable"
	mes a

画面にはStringVariableと表示されるはずです。

変数で計算する

で、もちろん数値型変数同士で演算することも可能です。


    a = 5
    b = 5
    c = a + b

これだと、cabを足した結果が代入されます。

加算以外に、もちろん減算乗算除算、全てオッケーです。

自分を含む式?

ところで、aを単に2増やしたいというときはどうすれば良いのでしょう。いちいち他の変数を用意していては面倒ですよね。

ここで、プログラミング言語独特とも言える式が登場します。


    a = 2
    a = a + 2

イコールの右側に、左側と同じ文字が出てきています。

数学的にはあり得ない式です。が、正しいのです。「"="は代入命令とされている」と説明しました。要するに、「確かに"="で結ばれてるけど、等しいというわけじゃない」ことを意味しているわけです。ですのでこれは、「aに、a + 2の結果を代入せよ」と命令していることになります。

ちなみにいちいちこんな風に書いてると長ったらしいので、複合代入演算子という便利なものがあります。


    a = 2
    a += 2  ;a = a + 2と同じ

コメントにありますが、a += 2a = a + 2と同じ意味です。当然ながら加減乗除全てについて、この演算子があります。a -= 2aから2を引く、a *= 2aに2をかける、a /= 2aを2で割る、ということになります。

変数の型

ここから先は説明気味なので、すっ飛ばしても構いません。何かここがひっかかってそうだというときにでも読んでください。

ところで、変数には「型」があります。というのは、その変数に何が入っているかを示すもので、HSPでは(日常的に使うもので)数値型、文字列型、実数型の3種類があります。数値型には数値(整数)が、文字列型には文字列が、実数型には実数(いわゆる小数)が入ります。注意して欲しいのは、数値型には整数しか入らないところです。小数を扱えるのは実数型になります。

C言語などでは変数を使うにはまず宣言する必要がありますが、HSPでは必要ありません。

そのため、HSPではわざわざ型を指定する必要がありません。代入する値が数値があれば自動で数値型になりますし、文字列であれば自動で文字列型になります。

なお、パラメータに文字列型変数を要求しているのに数値型変数を指定するなど、パラメータが求めているものと違う型の変数を指定するとエラーが出ますのでご注意を。

違う型の演算

ここでは文字列同士の結合も「演算」に入れておいて下さい。

さて、ここで非常に簡単な問題です。1÷2の答えはなんでしょうか。

小数で言えば0.5、分数で言えば1/2になりますね。プログラムでは基本的に分数ではなく小数で扱うので、これ以降小数で考えることにしましょう。

そんなわけでこれを表示してみましょう。1÷2は1 / 2と表します。


    mes 1 / 2

これを実行すると見事に期待外れな結果に出会います。0になるのです。1 / 2 = 0となってしまうのです。

ここで型を理解する必要が出てきます。

HSPでは、基本的に計算の結果は、その計算の最初に出てきた被演算子(被演算子については『2-3.計算をさせて表示させる』の『演算・演算子』を参照して下さい)の型になります。ここでは最初に'1'(数値型)が出てきているので、計算の結果も数値型になります。

ここで、変数の型の最初で説明した「数値型には整数しか入らない」ということが関わってきます。1 / 2の結果は0.5となるべきですが、数値型に変換されたために0になってしまったのです。

どうすれば0.5という結果を得られるのでしょうか。

計算の最初に出てきた被演算子の型に変換されるのなら、最初に出てくる型を実数型に変更してやれば、計算結果も実数になるはずですから、こうすれば良いということになります。


    mes 1.0 / 2

こうすれば0.5(ちゃんと書けば0.500000ですが)となります。

前節で5 + " num"が上手くいかないのも、これがあるためです。5 + " num"では、一番最初に'5'(数値型)が出てくるので、計算結果は数値型となり、文字列は消えてしまうのです。しかし、"" + 5 + " num"とすれば、最初に出てくるのは""(文字列型)なので計算結果は文字列型になり、望み通りの結果が得られるわけです。

型の変換

型変換。読んで字の如く、型を変換することです。

まず基本として、型変換が行われる場合は常にできるだけ情報を維持しようとします。

数値型が実数型変換されれば単に小数点以下が全部0の値になるだけです。整数'3'が代入されたaという変数を実数型に変換する場合、その'3'という数値を維持して実数型になるので、結果としては'3.000000'という値になります。

実数型が数値型に変換される場合、数値型で扱えるのは整数だけなので、整数部分は維持されます。しかし、どうしたって数値型で小数点以下は扱えないので、その部分については捨てられます。'3.141592'を数値型に変換すると'3'になります。(ちなみに四捨五入したいときは'+0.5'すると上手くいきます。)

ですが、文字列型の変換はどうなっているのでしょうか。

答えは、文字列の先頭から見ていって、数字以外が出たらそれ以降を捨てるです。

例を示しましょう。"0123abcd"という文字列を数値型に変換するとします。先頭から見て、数字以外が出てくるのは"a"のところです。なので、それ以降は捨てられ、"0123"という値が維持されます。先頭に0が来るのはあり得ないので、結果として'123'という数値になります。

これが"abcd0123"という文字列だったらどうでしょう。先頭から見ると、いきなり数字以外である"a"があります。この場合、全て捨てられて、変換結果は'0'という数値になります。

では7 + "num5" + 3.4 + "2.0ab"という式はどうなるのでしょうか。

まず最初に'7'があるので、演算結果は必ず数値型になります。次に"num5"という文字列ですが、これは最初に数字以外の文字があるので全て捨てられて'0'になります。次の'3.4'という実数ですが、これは数値型に変換されるときに小数点以下が切り捨てられて'3'になります。その次の"2.0ab"という文字列は、"2.0"以降が捨てられ、文字列としては"2.0"が残ります。その後、'2.0'を数値型に変換して、'2'になります。よって、この式は7 + 0 + 3 + 2という式になり、結果は'12'となります。

優先順位があったり

ところで"1 + 2 = " + ( 1 + 2 )としないと上手く表示されないのは何故でしょうか。

やはりこれも、演算結果の型が噛んできます。もしかっこなしで書いた場合("1 + 2 = " + 1 + 2)、最初に出てくるのは"1 + 2 = "なので演算結果は文字列型です。ここでは加算しかないので、左から順に計算していくのですが、そうするとこんな順番になります。

  1. "1 + 2 = " + 1を計算 -> "1 + 2 = 1"
  2. "1 + 2 = 1" + 2を計算 -> "1 + 2 = 12"

要するに、後ろの'1'も'2'も、文字列として演算されてしまうので、式は"1 + 2 = " + "1" + "2"という式になって、結果として出てくるのは"1 + 2 = 12"という文字列になってしまうわけです。

しかしかっこで括ってやると、小学校でも習ったのと全く同じで、かっこ内を真っ先に計算します。

  1. ( 1 + 2 )を計算 -> 3
  2. "1 + 2 = " + 3を計算 -> "1 + 2 = 3"

1 + 2の計算はもちろん数値型の3になります。その次の計算では、先に文字列型が来るので、全体の結果としてはかっこなしの場合と同様に文字列型です。

型については意外とハマることもあるので、覚えておいた方が良いと思います。

…………なんかごちゃついた説明ですこと。


Last Modified: 2008-08-15