
こんばんは
再帰についておしえてください。
実行結果は120となります。
F8で動作を追っていくと
Sample_subに5を渡してn<=1になるとENDIFにうつり
その後、END funtionとEndifの間をいききしております。
どうして、こういう動作をするのでしょうか?
よろしくおねがいいたします。
Sub sample()
MsgBox sample_sub(5)
End Sub
Function sample_sub(ByVal n As Integer)
If n <= 1 Then
sample_sub = 1 'ここで再帰処理は終了します。
Else
sample_sub = n * sample_sub(n - 1) 'ここで自分自身を呼び出しています。
End If
End Function
No.5ベストアンサー
- 回答日時:
VBA の
Function名 = 戻り値
って書き方に惑わされていませんか?
> sample_sub(5)
で呼び出したときの sample_sub=〜 と、その中の
> sample_sub = n * sample_sub(n - 1) 'ここで自分自身を呼び出しています。
にある sample_sub(n - 1) で呼び出されたときの sample_sub=〜 とは、別なものになります。
「一つの変数sample_sub」 の値が変化しているわけではありません。
ステップ実行で見ると、プログラムの同じ行を指しているので「一つの変数sample_sub」 の値が変化している」様に見えてしまいますが、そうではないのです。
別の例を用意します。
sample_sub(5) で呼び出したのと、同じ動きをする関数 sample_sub_5 を作ります。
Function sample_sub_5()
If 5 <= 1 Then
sample_sub_5 = 1
Else
sample_sub_5 = 5 * sample_sub_4()
End If
End Function
同様に4〜1を用意します
Function sample_sub_4()
If 4 <= 1 Then
sample_sub_4 = 1
Else
sample_sub_4 = 4 * sample_sub_3()
End If
End Function
Function sample_sub_3()
If 3 <= 1 Then
sample_sub_3 = 1
Else
sample_sub_3 = 3 * sample_sub_2()
End If
End Function
Function sample_sub_2()
If 2 <= 1 Then
sample_sub_2 = 1
Else
sample_sub_2 = 2 * sample_sub_1()
End If
End Function
Function sample_sub_1()
If 1 <= 1 Then
sample_sub_1 = 1
Else
sample_sub_1 = 1 * sample_sub_0()
End If
End Function
この sample_sub_5() での動作は、 sample_sub(5) とまったく同じになります。
いろいろとありがとうございました。
ご説明いただき徐々にわかっていったような気がします。
ご参考に 再帰のページをみつけました。
http://www.koikikukan.com/archives/2014/12/12-00 …
よろしければ見てください。
一番したのほうに120になる処理順序がかかれておりました。
確かにこのように動作してました。
長いあいだお付き合いいただきまして大変感謝しております。
本当にありがとうございました。
No.4
- 回答日時:
Function sample_sub2(ByVal n As Integer)
If n <= 1 Then
sample_sub2 = 1
Else
sample_sub2 = n * sample_sub3(n - 1)
End If
End Function
と書きました。
元のsample_subと(ほぼ)同じ内容ですから、結果も同じになります。
つまり
sample_sub(n - 1)
と書いても
sample_sub2(n - 1)
と書いても
結果は同じです。
再帰呼出がわからなくなる人は、「関数の先頭に戻る」と考えてしまうことが多いように思います。
> Sample_subに5を渡してn<=1になるとENDIFにうつり
> その後、END funtionとEndifの間をいききしております。
と考えてしまうのは、
> sample_sub = n * sample_sub(n - 1) 'ここで自分自身を呼び出しています。
で「関数の先頭に戻る」と考えてしまっていて、
End Functionまでいったら、呼び出し側の「MsgBox sample_sub(5)」に戻るのが「正しい」と考えてしまっているのでは?
ありがとうございます。 n=5のとき、sample_sub4 n=4のとき、sample_sub3
n=3のとき sample_sub2 n=2のとき sample_sub1
①この段階で、sample_subはemptyと表示されてます。
その後、If n <= 1 Then sample_sub2 = 1
IFが終わり、その後、n=1のときsample_sub 1
N=2のとき sample_sub 2 n=3のとき sample_sub 6
n=4のときsample_sub 24 N=5のときsample_sub 120
ーーーーーーーーーーー
①の段階でsample_sub1から4はそれぞれの領域のメモリにう格納され、IF文がおわったら、蓄積されたものをつかって、N=1から計算をしているのでしょうか?また、そのときどして値がN=1からN=5に順にふえるのでしょうか?②前回 実行結果が120と表示されていたので120と記載したのですが・・・sample_sub2 = n * sample_sub3(n - 1)のときに たとえば、N=3のきにsample_subが6になるのでしょうか?(このとき、sample_sub2 =3*sample_sub3(n-1)どのようにして6とみちびきだせるのでしょうか?)よろしくお願いいたします。
No.2
- 回答日時:
私は、このように考えました。
If ~ End If 構文がネストになっていると同じことではないでしょうか。
ネストは、If の中にIf があって・・・・と続くから、当然、End If も処理しないと終われないと同じようなことではないかと思います。
No.1
- 回答日時:
再帰関数は、「別の関数を呼んでいる」と考えると、理解の助けになると思います。
例えば
Function sample_sub(ByVal n As Integer)
If n <= 1 Then
sample_sub = 1
Else
sample_sub = n * sample_sub2(n - 1)
End If
End Function
Function sample_sub2(ByVal n As Integer)
If n <= 1 Then
sample_sub2 = 1
Else
sample_sub2 = n * sample_sub3(n - 1)
End If
End Function
というように。
さて、このとき、 動きを考えると
sample_sub:
sample_sub = n * sample_sub2(n - 1)
→
sample_sub2: sample_sub2 = n * sample_sub3(n - 1)
→
... sample_sub3: End Functionで 戻ってくる
sample_sub2: End If
sample_sub2: End Functionで 戻ってくる
sample_sub: End If
sample_sub: End Functionで 戻ってくる
これはわかりますね?
これが、実際は sample_sub という一つの関数を再帰呼び出ししたものなので、見た目では 「endifとend functionを繰り返している」ように見えています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) あるフォルダーのファイルを違う親フォルダーのサブフォルダーに移したい 11 2023/02/15 19:00
- Visual Basic(VBA) 標準モジュール Public mOnTime As Date Sub sample() '実行プロシ 1 2023/02/22 15:44
- Visual Basic(VBA) VBAでファイルを開くプログラムがエラーです 2 2023/02/21 16:56
- Excel(エクセル) エクセルVBAでオブジェクトが必要です 2 2022/09/10 16:37
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) まとめシートから集計シートへA列のコードが一致したら1行コピーするマクロをネット上で見つけました。こ 1 2022/08/30 14:11
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) [Excel VBA] このコードでは行の挿入や行の消去をすると13のエラーが出てしまう。 3 2022/12/09 00:29
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA public変数はどのようなこ...
-
Excel VBA: private sub 内の...
-
VBAでcallで呼び出したsubを終...
-
チェックボックスを操作できな...
-
VB.NETでのイベントの途中終了
-
パスカル言語
-
VBAで入力数値について
-
【VB6.0】 あるフォームから他...
-
C#のループでtextboxに値を入れ...
-
エクセルVBAでテキストボッ...
-
マクロでマクロを実行
-
Pascalでの選択ソート
-
texで図と表を並べたい
-
スタイルシート
-
ユーザーフォームへのデータ入...
-
String型の値にスラッシュをつ...
-
VB.NET)コンボボックスの連動に...
-
VBSのプログラム
-
文字列の中からある文字の個数...
-
ExcelのVBA。Staticな変数について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA public変数はどのようなこ...
-
GetNextWindowがDLLファイルUse...
-
演奏記号の・・・・
-
Excel VBA: private sub 内の...
-
VB6.0の正規表現を使って、文字...
-
イギリス海軍のsub lieutenant...
-
他のフォームから別のフォーム...
-
エクセルVBAでテキストボッ...
-
VB.NETでのイベントの途中終了
-
チェックボックスを操作できな...
-
【VB.NET】テキストボックスに...
-
レコードセットにnullの場合
-
アクセスできない保護レベルエ...
-
C#のループでtextboxに値を入れ...
-
ユーザーフォームへのデータ入...
-
タイムアウトする仕組みを作りたい
-
C言語のサフィックスについて
-
String型の値にスラッシュをつ...
-
テキストボックスかラベル上の...
-
VBAで入力数値について
おすすめ情報
こんばんは
ご回答ありがとうございます。
すみません。基本的なことでもうしわけございません。
Function sample_sub(ByVal n As Integer)
If n <= 1 Then
sample_sub = 1
Else
sample_sub = n * sample_sub2(n - 1)
End If
End Function
-------------
のとき、 どしてsample_sub2(n - 1)なのでしょうか?
よろしくお願いいたします。
丁寧な説明ありがとうございます。
なんとなくわかりました。わかったつもりかもしれません。すみません。
計算の流れとして、(先ほどのご回答いただいた流れから)
sample_sub_5を求める場合、=5 * sample_sub_4()なのでsample_sub_4()
が呼び出され、sample_sub_4 = 4 * sample_sub_3()なので、 sample_sub_3()に
さらにお伺いを立て・・・N=1のときは sample_sub_1 = 1なので、そこを起点に計算され、結果sample_SUB_5がもとめられ、sample_SUBへ渡されるということでしょうか?
もしくは、end if endfunctionを行き来していた時、ウォッチりすとでみたら、N=1から順に5までへんかしていたので全然違う方法で処理がおこなわれているのでしょうか?
宜しくお願いいたします。