例題その 1

問 1. 二つの整数の和、差、績、及び商を求めなさい。

これを Pascal で考えると以下のようになります。


program sampleOperation(output);
var m, n, sum, dif, mul, divide: integer;
begin
  m := 5;
  n := 3;
  sum := m + n;
  dif := m - n;
  mul := m * n;
  divide := m div n;

  writeln(m, n, sum, dif, mul, divide);
end.

ちょっと説明を加えましょう(Pascal のコメントは「//」や「{* 〜 *}」などですが、ここの説明には「#」を使っていますのでお間違いなきようお願いします)。

program sampleOperation(output);

# Pascal の場合「プログラムヘッダ」には「プログラム名」と「入力」もしくは「出力」を書きます。ここは次のように読めます。
「プログラム名『sampleOperation』は(入力はなくて)出力をするプログラムである」

var m, n, sum, dif, mul, divide: integer;

# ここは宣言部分です。
# 「var」は「variable(変数)」のことです。その後「:(コロン)」まで続くのが変数名で、最後に型名がきます。ここでは「integer(整数)」型ですので、ここは次のように読めます。「整数型の変数として、m、n、sum、dif、mul、divide を定義する」
# ここで使っている「m」と「n」はとりあえず何でもいいや的命名ですが、残りの変数名は「sum(合計)」「dif(difference:差)」「mul(multiple:掛ける)」「divide(divide:割る)」など一応理屈に合った命名をしております。
# 「div」というのは関数名に使われているので「divide」にしました。
# 「変数」というのは数値や文字などを一時的に格納しておいて計算などに利用するためのもので、実際にはコンピュータのメモリのどこかの番地を指しているのらしいのですが、とりあえず何かを入れとく容れ物だと思ってください。宣言というのは、それを使うから用意しとけよ、とコンピュータに命令している訳ですね。言語の本には「宣言をしないと使えません」と書いてあるけれど、それってコンピュータ様の方が偉そうなので、反対に「宣言するから用意しとけよ」という方がいいですね。
# Pascal は几帳面なので最初に宣言しておかないと変数が使えません。

# 次がプログラムの実行ブロック部分です。
# Pascal のプログラムブロックは「begin」で始まり、「end」で終わります。一番最後は「end.」とピリオドが付きます。

begin
  m := 5;
  n := 3;

# 左の項に「:=」で右の項を代入しています。C や Basic では「m = 5;」などになりますが、Pascal は「:=(コロン + イコール)」です(横になった顔文字ではありません :-)。
# ここでは最初に宣言した変数「m」と「n」にそれぞれ「5」と「3」を代入しているわけですね。ここも言葉にするとこんな感じですかね。
「プログラムを開始する。まず変数『m』に『5』を代入する。次に変数『n』に『3』を代入する」

  sum := m + n;
  dif := m - n;
  mul := m * n;
  divide := m div n;

# ここでは右の項で計算した結果を左の項に代入しています。
# 「+」「-」はそのままですが「*」は「×」で「div」は「割り算をした答えの整数部分のみ取り出す」関数です。「divide」君、余りは気にかけてません。
「変数『sum』に変数『m』の値と変数『n』の値の和を代入する」などなどです。

  writeln(m, n, sum, dif, mul, divide);

# 「writeln」は「write line」でコンソールに1行出力して改行する関数です。ここで答えを全部書き出しています。
「コンソールに『m』『n』『sum』『dif』『mul』『devide』に格納された値を表示して改行する」

end.

# プログラム終了。

コードの中で PocketStudio にないのは「writeln」です。もちろん PocketStudio の問題ではなく Palm がコンソールを持っていないからですね。プログラムの実行も UNIX やWindows のように「run」コマンドで動作するのではなく、イベントドリブンといってボタンをタップするなどのユーザーが何かアクションを起こした時に初めて動作するところが違います。Macintosh も初めからイベントドリブンのシステムですから Palm と同じです。もちろん Palm でもアプリケーションが立ち上がった時のスタートアップのイベントで、すぐに実行させることも可能ですが、ユーザーにとってはタップした途端にプログラムが始まることになり、「アプリケーションを立ち上げただけで、まだ何もしてないよ!」と言われそうなので、必要なければ止めておいた方が無難かと思います。

さて、この最初のプログラムがきちんと動作するかどうかを PocketStudio で確かめるには、ボタンをひとつ作って、それをタップしたらこのプログラムが実行されるようにしておけばいいと思います。でもコンソールがないから「writeln」が使えませんが、文字を表示するところとしては「メッセージボックス」「テキストフィールド」「ラベル」などそれなりに勝手に文字を表示する場所が転がっていますが、とりあえず「writeln」の代わりに直接フォームに書き込むことにします。

PocketStudio のプロジェクトを作成

PocketStudio を立ち上げて新規プロジェクトを作成します。名称は「SampleOperation」としました。フォームに必要なのはボタンたった 1 個だけです。
ボタンを置いてダブルクリックし、コードのウィンドウを立ち上げます。以下入力したコードです。

// これはさきほどのものと同じです

var m, n, sum, dif, mul, divide: Integer;

// ここが違います。

sumStr, difStr, mulStr, divideStr:array[0..128] of Char;

// ここまでの部分も同じです

begin
  m := 5;
  n := 3;
  sum := m + n;
  dif := m - n;
  mul := m * n;
  divide := m div n;

// ここは表示のための部分です

  StrIToA(sumStr,sum);
  StrIToA(difStr,dif);
  StrIToA(mulStr,mul);
  StrIToA(divideStr,divide);

// 何を表示しているのか分からなくならないように、ラベルをつけておきます

  WinDrawChars('sum = ',5,30,50);
  WinDrawChars('dif = ',5,30,60);
  WinDrawChars('multi = ',5,30,70);
  WinDrawChars('divide = ',5,30,80);

  WinDrawChars(sumStr,2,80,50);
  WinDrawChars(difStr,2,80,60);
  WinDrawChars(mulStr,2,80,70);
  WinDrawChars(divideStr,2,80,80);

// 表示する結果をとりあえず 2 桁分用意しました

  Handled := True;
end;

Palm にはコンソールがないので、文字を表示する場所を用意してやらねばなりません。今回は直接フォームに書き込むことにしましたが、そのために必要なものは「WinDrawChars()」で、これは Pascal の関数ではなく Palm OS の API です。Palm OS Reference.pdf を見ると次のように書かれています。

「WinDrawChars()」ウィンドウにキャラクタを描く。何も返さない。

Prototype void WinDrawChars (const Char *chars, Int16 len, Coord x, Coord y)

使い方は「WinDrawChars(書き込む文字列へのポインタ,、文字列の長さ:バイト数、表示する位置の X 座標、表示する位置の Y 座標)」となっています。

ということは書き込むまでの作業は次のようになります。

1) 計算された結果を整数型(Integer)から文字列に変換して変数に格納する
2) WinDrawChars() で表示

計算された結果は、sum, dif, mul, divide、に格納されていますが、これは整数型ですので文字列にしなければなりません。整数型から文字列への変換は「StrIToA()」を使います。これは「String Integer to Ascii」の略で、これは PocketStudio の Language ヘルプにあります。StrIToA(文字列型の変数, 整数型の変数)という使い方です。
PocketStudio には Delphi の String 型がないため、Char 型の配列を利用することになります。String型があると結構楽なんですけどね。

sumStr, difStr, mulStr, divideStr:array[0..128] of Char;

StrIToA を使うために宣言部で Char 型と PChar 型の変数を宣言しています。今回のプログラムの場合 Char 型にこんな長さはいりませんが、そこは教科書ではないということで。

StrIToA(sumStr,sum);

結果の格納されている整数型変数 sum を文字列型に変換して、それを sumStr に格納しています。他も同様です。

WinDrawChars('sum = ',5,30,50);

ただ数字だけを表示したのでは何だかわかりませんので、ラベルをつけます。これも同じ WinDrawChars() を使っています。

WinDrawChars(sumStr,2,80,50);

整数型から変換した文字列を表示しています。

コンパイルしたプロジェクトを Palm 上でテストしてみましょう。

ボタンをクリックするとコードが実行されます。

あれ、数字の後ろに何か四角い豆腐のようなものが表示されてますね。

これ、なんでしょう ->山田さん

山田 「多分End of charの0でしょう。PalmOSでは表示できない(Printableではない)文字を無理やり表示するとこの豆腐が現れます。文字数を取り出さないといけませんね」

なるほど。適当に 2 バイト分取っておいたけど、1 バイトの場合は最後のものがくっついてくるんですね。というわけで、以下の部分に文字数を取り出す関数を追加します。
文字数を取り出すのは「StrLen()」です。

《修正前》
  WinDrawChars(sumStr,2,80,50);
  WinDrawChars(difStr,2,80,60);
  WinDrawChars(mulStr,2,80,70);
  WinDrawChars(divideStr,2,80,80);

《修正後》
  WinDrawChars(sumStr,StrLen(sumStr),80,50);
  WinDrawChars(difStr,StrLen(difStr),80,60);
  WinDrawChars(mulStr,StrLen(muStr),80,70);
  WinDrawChars(divideStr,StrLen(divideStr),80,80);

もう一度コンパイルし直します。これで豆腐はなくなりました。今晩は冷やっこですね。

Pascal で書ける部分と、Palm API に依存する部分とを明確に分けて考えた方が理解しやすいと思います。また今回は直接 Palm API を使いましたが、PocketStudio には PSLibrary という便利なものが準備されており、直接 Palm API を使うよりは遥かに簡単に同じことが実現できるようになっています。PocketStudio 自体情報が少なく、ドキュメントも余りありません。少しずつ苦労しながら Pascal を試していきたいと思います。



copyright(C)2002 Hacker Dude-san all rights reserved.