定数とは

定数とは、プログラム中で値を変更することのできない変数で、!定数名とは変数=「値」のように指定します。マニュアルでは、変数>グローバル変数の項目に以下のように書いてあります。

オプション指令「!」をつけて以下のように宣言した変数は強制的にグローバルな定数になります。定数は書き換えすることができない変数です。

「!」をつけて宣言した定数は、プログラム実行前のプリプロセスの段階で定義されます。

また似たような用語としてリテラルがありますが、リテラルはプログラム中に直接書かれる定数のことを指し、例えば1234「文字列」のように、やはりプログラム中で変更されることのない値です。しかし、これらは上の定義でいう所の定数とは違うものです。

しかし、それではなぜ定数というシステムがあるのでしょうか?直接プログラム中にリテラルを書くのと実質同じはずなのに、回りくどい定数を使うと便利な場面はあるのでしょうか?

定数の性質

まず、定数の性質を確認しておきましょう。

  • 構文木解析より前(つまり実際に実行されるよりも前)で値が設定される
  • その値はプログラム中で変更することはできない
  • その値を使うときは、普通の変数と同様、定数名を書く

ちなみに、構文木解析前の段階で値が設定されることを利用して、その段階で本来実行されることのないコードを無理矢理実行させるという裏ワザも存在しますが、余り使い道がないのでここでは紹介しません。

定数の使い所

定数の使い所はズバリ、リテラルの代わりに使えることです。例えば、何度も同じリテラルを書いた経験はありませんか?よくあるのは例えばキー番号やソフト名などです。

エンターキーのキー番号は13で、この値はキーボードの仕様が変わらない限りは不変のはずですよね。でももしこの値を暗記していなければ、必要になる度に何度も調べて13というリテラルをプログラム中に書かなければなりません。

ソフト名も同様で、自分でつけたソフトの名前でも、他の場所で必要になって前書いた所を探してコピペしたり、ソフト名を変更したために何か所も書き直す必要が出てきたりします。

こういった状況の生じるリテラルを、定数で置き換えていくのです。そうすれば、キー番号を忘れても調べ直す必要はなく、ソフト名を変更する時も一か所の変更で済みます。

リテラルを定数に置き換える
!ソフト名とは文字列=『定数はこう使う!』
!バージョンは1.02
!Enter=13
!メモ帳=『notepad.exe』

母艦のテキストはソフト名&『Ver.』&バージョン

メモ帳を起動。
『あいうえお』をキー送信
Enterを仮想キー送信
『abcdef』をキー送信
Enterを仮想キー送信
 

さらに、生のリテラルで記述するよりもコードの可読性が上がり、コードメンテナンス性が高まるのも大きな利点です。13とだけ書いてあってはそのプログラムが意味する所はすぐ分かりませんが、Enterを仮想キー送信と書いてあれば何のことか一目瞭然ですよね。他にも上のサンプルでは!メモ帳=『notepad.exe』という例を使っていて、やはりメモ帳を起動という分かりやすい記述にすることができます。

もっともエンターキーの仮想キー番号が13であることも、メモ帳の名前が「notepad.exe」であることも、覚えてしまっている人は覚えているわけですから、この例では余り実用的とは思えないかもしれませんね。

二次元配列などのカラムインデクスに使う

二次元配列(表データ)を扱う際に、行(ロウ)と列(カラム)の2つについてインデクスを指定しなければなりません。一般的な表を扱う場合は、行の方が動的な値による指定、列の方が静的な値による指定になります。つまり、行の方はプログラムが関わり変数などによりインデクスを指定するのに対して、列の方は大体プログラムが書かれた時点で固定されたリテラルによるインデクス指定になることが多いのです。

例として、n人分の顧客データ(氏名・性別・年齢)が格納された配列を考えてみます。年齢が35歳未満の人の性別に関するデータを得たい場合、まず年齢データの2列目を見て30歳以上の人がどの行にいるかを調べ、その各行について性別データの1列目を見ればいいことになります。もちろん、配列を扱っているのだから、氏名が0列目であることに注意してください。

顧客データ
氏名 性別 年齢
クジラ 31
佐藤 花子 26
大和 なこ 21
山田 太郎 40

※もちろん、実際の人物とは関係ありません。このデータは架空のものです。

二次元配列のカラムインデクスを定数で指定
# カラムインデクス
!氏名=0
!性別=1
!年齢=2

# 氏名,年齢,性別
顧客データとは配列=『クジラ,男,31
佐藤 花子,女,26
大和 なこ,女,21
山田 太郎,男,40』をCSV取得したもの
集計とはハッシュ

顧客データを反復
 もし対象[年齢]が35未満ならば
  集計@対象[性別]=集計@対象[性別]+1
集計を言う
 

対象[1]などではその列のデータが何を指しているのかぱっと分かりにくいですが、このように定数指定にすることで分かりやすくできます。さらに、例えば0列目を顧客IDのデータにして、他の列を全てずらしたい場合なども、定数部分を書き換えるだけで済むという利点があります。

まとめると、表データを扱うときは、プログラムの目的とデータの構造に対応してカラムインデクスが固定されている場合が多く、これを定数で指定すると、前章同様、可読性コードメンテナンス性が向上する、ということです。

なお、上のサンプルでは反復構文を使っているので、行のインデクスの指定は出てきませんでした。いずれにせよ、行インデクスの方は、反復構文に隠れて必要なかったり、検索命令の結果の値が使われたりと、列のように安定した使われ方ではないということです。