OriosのActiveBasic講座(1-4):やってみようの答え(1-4)

1.配列
【問題】
ユーザに1月・2月・3月それぞれの身長・体重を入力してもらい、3ヶ月の身長・体重の平均を求めるプログラムを作ってみよう。 ただし平均を求める部分では平均を求める関数を作ってみましょう。 (注:一次配列を使ってください。AB3.08a現在Input命令語で二次配列を使うとフリーズします。)
【解答例】
#console
Dim height[2] As Double 'Dim height(2) As Doubleでも可だが非推奨。以下同じ(2005/05/12)
Dim weight[2] As Double
Dim i As Word
For i = 0 To 2
    Print Str$(i + 1) + "月の身長と体重を入力 -->";
    Input height[i], weight[i]
Next
Print "身長の平均:" + Str$(average(height, 3))
Print "体重の平均:" + Str$(average(weight, 3))
Sleep(3000)
End

'平均を求める関数
'(汎用性を持たせるために一応要素数を指定するようにしています。
'しかし要素数を指定せずForループを「i = 0 To 2」としても別に構いません。)
Function average (ByVal data As DoublePtr, ByVal element As DWord) As Double
    Dim i As DWord
    For i = 0 To (element - 1)
        average = average + data[i]
    Next
    average = average / element
End Function
【解説】

配列をどう宣言し利用するかがポイントとなります。 配列の特徴は同じような種類の数値をまとめて扱うことができるという点です。 なので身長をまとめた配列・体重をまとめた配列を作るのがいいでしょう。 そして宣言された配列をうまくForループと組み合わせることもポイントです。 また配列をプロシージャに渡すときにはカッコのない配列名 だけを使うことに注意しましょう。

2.構造体
【問題】

あらかじめ今年の西暦をユーザに入力してもらい、その後、名前・生まれた年をユーザに入力してもらったら、名前とその人の年齢を表示するプログラムを作ってみましょう。 ただし以下の条件を満たしてください。

  • 名前と生まれた年をあらかじめ保存できる構造体を作って利用する。
  • 年齢の計算と表示はSubブロックの中で行う。
  • 表示の際にはタブ区切りを使う。
※ 年齢は現在の西暦からその人が生まれた年を引いて算出するようにすれば構いません。
【解答例】
#console
'(1)構造体・変数・プロシージャの名前などは適当に
'(2)With 〜 End Withは入れても入れなくても可
Type PERSONDATA
    name As String
    birth_year As Integer
End Type
Dim now_year As Integer
Dim persondata As PERSONDATA
Input "現在の西暦を入力してください -->", now_year
With persondata
    Input "名前と年齢をコンマで区切って入力してください -->", .name, .birth_year
End With
PrintAge(now_year, persondata)
Sleep(3000)
End

Sub PrintAge(ByVal ny As Long, ByRef pd As PERSONDATA)
    Dim age As Integer
    age = ny - pd.birth_year
    Print pd.name, age
End Sub
【解説】

lesson1-4-2の冒頭のプログラムと似ていますが、ポイントは自分できちんと構造体が使いこなせているかどうかです。 ポイントは次の4つが挙げられると思います。 これができていたら構造体は大丈夫でしょう。

  • 構造体をきちんと宣言できている。
  • 構造体を使えるようにDimで準備できている
  • 実際に構造体に代入などができている
  • 構造体をきちんとプロシージャ内で利用できている
3.文字列ポインタ
【問題】

ユーザから入力された文字列(半角文字のみ)を、全ての文字の間に「・」をはさんで、それをダイアログボックスで表示するようなプログラムを作ってみましょう。 例えば「Orios」と入力されたなら、「O・r・i・o・s」と表示するようにします。


【ヒント】
  • 何文字入力されるか分からないものの全ての文字に対して何か処理を行うときはループを使うとうまくできます。
  • 「・」は全角文字、つまり2バイトです。
【解答例】
' 変数名・ダイアログボックスのタイトルバーなどは適当に
#console
Dim input_str As String
Dim str As BytePtr
Dim i As Integer
Input "何か文字(半角)を入力してください -->", input_str
' 文字の長さは、「入力された文字」+「間にはさむ『・』」+「NULL文字」です。
' (注) 間にはさむ「・」は文字の数より1つ少ないです(植木算の考え方)。
str = calloc(Len(input_str) + 2 * (Len(input_str) - 1) + 1)
lstrcpy(str, Chr$(input_str[0]))
For i = 1 To Len(input_str) - 1
    lstrcat(str, "・")
    lstrcat(str, Chr$(input_str[i]))
Next
MessageBox(0, str, "lesson1-4-3-try", MB_OK)
free(str)
End
【解説】

今回は「String型を使わない文字列」をきちんと扱えているかがポイントです。 以下の点がきちんとできているか確認してみましょう。

  • BytePtr型を使っているか?
  • calloc関数によるヒープ領域からの確保ができているか?
  • lstrcpy・lstrcat関数による代入・連結ができているか?
  • free関数による記憶領域の解放を忘れていないか?

あとは問題の処理の方法ですが、「最初の文字だけはlstrcpy関数を使わないといけない」「文字と文字の間にだけ『・』をはさむ」と考えると、入力された文字を最初の文字だけ別に処理して、あとは「・」と「次の文字」を1セットと考えてForループを使えばうまくいきます。 もちろん他のWhileループなどを使っても構いません。


ご質問・ご意見・ご感想・苦情等はメールまたはメイン掲示板のActiveBasic板などでお気軽にどうぞ。

前に戻る - 次に進む

ホーム > OriosのActiveBasic講座(トップページ) >