メソッドには、subとFunctionがありますが、どちらを使えばよいのか
わからないことがあります。戻り値の有無と説明されてますが、
その戻り値についても判断しかねる場合が多々あります。
下記は、タイピングゲームを作ってみたのですが、いちおうsubメソッドで
作成しました。
これをFunctionでも記述できると思うのですが、その場合の記述の仕方が
今ひとつ理解が及びません。できれば、ご教授お願いします。
(ファイルをLabel1に読み込み全文を確認してから、スタートを押すと
テキストボックスに1行ずつ文字列が表示されます。
ストップでタイピングに要した時間が表示されます。)
Imports System.IO, System.Text
Public Class Form1
Dim count As Integer
Dim total As Integer
Dim fname As String
Dim n As Integer = -1
’スタートボタン
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox4.Visible = True
Label1.Visible = False
If Label1.Text = "" Then
MessageBox.Show("ファイルを読み込んでください")
Else
mondai()
End If
End Sub
’ストップボタン
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Stop()
TextBox2.Text = total.ToString & "秒です"
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
count += 1
total = count
End Sub
’問題文を1行ずつ表示するメソッド
Private Sub mondai()
TextBox1.Focus()
ImeModeBase = Windows.Forms.ImeMode.Hiragana
count = 0
Timer1.Start()
TextBox1.Text = ""
TextBox2.Text = ""
Dim line As Integer
line = File.ReadAllLines(fname).Length
Dim str(line - 1) As String
Dim sr As StreamReader = New StreamReader(fname, Encoding.Default)
n += 1
For i As Integer = 0 To n
If i < line Then
str(i) = sr.ReadLine
TextBox4.Text = str(i)
Else
n = -1
End If
Next
sr.Close()
End Sub
'ファイルをLabel1に読み込む
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
TextBox4.Visible = False
Label1.Visible = True
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Label1.Text = System.IO.File.ReadAllText(OpenFileDialog1.FileName, Encoding.Default)
fname = OpenFileDialog1.FileName
End If
End Sub
End Class
> その戻り値についても判断しかねる場合が多々あります。
具体性が無い記述なので意味が理解できません。
何をどう判断しようとして、どんな場合になぜ判断しかねているのですか?
早速のレス感謝します。
>具体性が無い記述なので意味が理解できません。
すみません。
例えば上記の場合は、各行の問題文が戻り値になると思うのですが
違うのですか?
> 例えば上記の場合は、各行の問題文が戻り値になると思うのですが
> 違うのですか?
仕様次第でしょう。つまりプログラマがどう作るかを決めます。
関数内でエラーが起こったら False を返すでも良いのでは?
もともとプログラムというものに正解などありません。
どう作っても構いません。
判断基準は仕様(要望)を満たしているかどうかです。
>もともとプログラムというものに正解などありません。
>どう作っても構いません。
>判断基準は仕様(要望)を満たしているかどうかです。
有り難いお言葉です。
タイピングゲームは、とある本のサンプルですが、オブジェクト指向
で書かれていたので、自分なりに書き直してみたものです。
オブジェクト指向は考え方としては、理解しやすいプログラミングの技法
なのでしょう。しかし、私のように一人でちまちまと趣味でやる人間にとってはあまり必要ではないと思っています。
> しかし、私のように一人でちまちまと趣味でやる人間にとってはあまり必要ではないと思っています。
その意見には賛同しかねます。
> 理解しやすいプログラミングの技法
とおっしゃるなら、参考にすべきでは?他人にとってと言うことでしょうか?他人にとって
理解しやすいのであれば、自分の頭の中を整理するのに役立つでしょう。
また、公共の場である質問掲示板で質問している時点で、他人に説明する力が必要になります。
ならば、むしろ積極的に取り入れるべきという結論になりそうなものですが?
結局、戻り値の話がどこかに行ってしまいましたが。。。
繰り返しますが、
> 何をどう判断しようとして、どんな場合になぜ判断しかねているのですか?
>他人にとって理解しやすいのであれば、自分の頭の中を整理するのに役立つ>でしょう。
>また、公共の場である質問掲示板で質問している時点で、他人に説明する力>が必要になります。
>ならば、むしろ積極的に取り入れるべきという結論になりそうなものですが
確かにその通りだと思います。
ただ、いろいろと表記の仕方が面倒というか、消化しきれていないからなのでしょう。オブジェクト指向は、今後少しずつ勉強していきたいと思います。
> 何をどう判断しようとして、どんな場合になぜ判断しかねているのですか?
戻り値という概念が理解できていないのかもしれません。
メソッドをFunctionにして下記のように書き直してみましたが
これでは、要素数を超える回数をクリックすると「インデックスが配列の境界外です。」というエラーをはきます。
Imports System.IO, System.Text
Public Class Form1
Dim count As Integer
Dim total As Integer
Dim fname As String
Dim n As Integer = -1
Dim i As Integer
’スタート
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox4.Visible = True
Label1.Visible = False
If Label1.Text = "" Then
MessageBox.Show("ファイルを読み込んでください")
Else
mondai(i)
End If
End Sub
’ストップ
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Timer1.Stop()
TextBox2.Text = total.ToString & "秒です"
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
count += 1
total = count
End Sub
'問題文を表示するメソッド
Function mondai(ByVal i As Integer) As String
TextBox1.Focus()
ImeModeBase = Windows.Forms.ImeMode.Hiragana
count = 0
Timer1.Start()
TextBox1.Text = ""
TextBox2.Text = ""
Dim line As Integer
line = File.ReadAllLines(fname).Length
Dim str(line - 1) As String
Dim sr As StreamReader = New StreamReader(fname, Encoding.Default)
n += 1
For i = 0 To n
If i < line Then
str(i) = sr.ReadLine
TextBox4.Text = str(i)
Else
n = -1
End If
Next
sr.Close()
Return str(i)
End Function
'ファイルをLabel1に読み込む
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
TextBox4.Visible = False
Label1.Visible = True
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Label1.Text = System.IO.File.ReadAllText(OpenFileDialog1.FileName, Encoding.Default)
fname = OpenFileDialog1.FileName
End If
End Sub
End Class
> メソッドをFunctionにして下記のように書き直してみましたが
> これでは、要素数を超える回数をクリックすると「インデックスが配列の境界外です。」というエラーをはきます。
定時のコードで戻り値は使ってないわけですし、普通にバグなのでデバッグしてください。
失礼。誤字です。
×定時
↓
○提示
簡単な例で申し訳ないのですが、数を2倍にするメソッドを作ってみました。
下記のコードでは、subでもFunctionでもどちらも結果は同じになります。
ということはこの場合はどちらでも良いという結論で良いのですか?
この2つのメソッドを使い分ける判断というか切り分けが知りたいのです。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
sbaisuu(4)
End Sub
Private Sub sbaisuu(ByVal i As Integer)
TextBox1.Text = (i * 2).ToString
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Fbaisuu(4)
End Sub
Function Fbaisuu(ByVal i As Integer) As Integer
TextBox2.Text = (i * 2).ToString
Return i
End Function
関数を呼び出して、そのなかで処理が完結するならばSubを使えば
いいのではないでしょうか。
呼び出された関数で処理をして、その結果を呼び出し側の処理で
必要ならFunctionを使えばいいと思います。
最初の投稿されているコードにではmondaiを呼び出すところで
引数もないようですし、呼び出したあとで、呼び出し側で処理も
していないので、Functionを使う必要はないようにおもいます。
次に投稿されたコードでは引数としてiを渡していますが
For文のところで初期化されてしまっていますよね。
Functionを使うために渡しているんでしょうか?
Functionを使うときでも別に引数も戻り値もなくても、問題なかった
と思います。
まあ、それならSubを使えってことになるんですが、、、
>Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As >System.EventArgs) Handles Button2.Click
> Fbaisuu(4)
> End Sub
> Function Fbaisuu(ByVal i As Integer) As Integer
> TextBox2.Text = (i * 2).ToString
> Return i
> End Function
Fbaisuuを呼び出してるほうで戻り値を受け取ってないですし
それを使って処理もしてないので(SubもFunctionも関数のなかで
テキストボックスへ表示してるので)結果は同じだと思います
もしFunctionを使う練習なら
計算だけFbaisuuで行って、その戻り値を受け取って、
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
のなかでテキストボックスへの表示を行ってみてはいかかでしょう。
ひよこさん、すみません。
こんな感じですか?
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
TextBox2.Text = Fbaisuu(4).ToString
End Sub
Function Fbaisuu(ByVal i As Integer) As Integer
Dim k As Integer = i * 2
Return k
End Function
おぉ。すごい!TextBox1 の処理も同じ関数で書ける!
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Text = Fbaisuu(4).ToString
End Sub
あら、いいところをまるるさんに。。。(笑
あとは、上記のコードで思ったとおりの動きが出来ている
と思うので、特にいうこともないでしょう。
関数のいいところもまるるうさんの投稿でおわかりでしょうし。
これで、問題は解決されたでしょうか。
>これで、問題は解決されたでしょうか
何とか見えてきたように思います。
今後さらに学びを深めていきたいと思っていまが
行き詰まったら、またご助言を仰ぎたいと思っていますので
よろしくお願いします。
特攻隊長まるるうさん、 ひよこさん、本当に有り難うございました。
誤字がありましたので訂正します。失礼しました。
>これで、問題は解決されたでしょうか
何とか見えてきたように思います。
今後さらに学びを深めていきたいと思っていますが
行き詰まったら、またご助言を仰ぎたいと思っていますので
よろしくお願いします。
特攻隊長まるるうさん、 ひよこさん、本当に有り難うございました。
本を買うことは、単に勉強だけの話ではない。
Visual製品は、きちんと正式に稼動しているか検査もできる。
ニセもの製品だと動かないコードがあるかもね。
ツイート | ![]() |