これは、コマンドプロンプト(cmd.exe) Advent Calendar 2015 - Qiitaの14日目の記事です。※Windows 10 Home 64bit 搭載のcmd.exeにて検証を行っています。
さて、お代の通り、BATファイルでfibコマンドを実装します。
……が、普通に作ってしまうと再帰呼び出しになってしまってアレなので、まずは別言語で試してみます。

  • ①ただの再帰で実装
  • ②末尾再帰で実装
  • ③展開してGOTOに
  • ④BATファイル化
という順番でやります。
### ①ただの再帰で実装 後でGOTOを使うことも考えて、とりあえずCで実装します。 ```c #include int main(void){ printf("%i", fib(10)); } int fib(n) { if (n == 0) { return 0; } else if (n == 1) { return 1; } else { return fib(n-1) + fib(n-2); } }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</div>
<div class="section">
    ### ②末尾再帰で実装
    つまり、1つ前の結果と2つ前の結果を足す、ってことなので・・・<br/>
(aが1つ前の結果、bが2つ前の結果)
```c
#include <stdio.h></stdio.h>
int main(void){
    printf("%i", fib(10));
}
int fib(n) {
    return fib_sub(n, 1, 0);
}
int fib_sub(n, a, b) {
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return a;
    } else {
        return fib_sub(n - 1, a + b, a);
    }
}

### ③展開してGOTOに 末尾再帰にできたので、gotoを使ったループに展開します ```c #include int main(void){ printf("%i", fib(10)); } int fib(n) { int a; int b; int swap;
a = 1;
b = 0;
swap = 0;

loop: if (n == 0) { return 0; } else if (n == 1) { return a; } else { n = n - 1; swap = a + b; b = a; a = swap; goto loop; } }

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
</div>
<div class="section">
    ### ④BATファイル化
    ではこれを、BATファイルで書き直します。
```dosbatch
@echo off

set /a n = %~1
set /a a = 1
set /a b = 0
set /a swap = 0

:LOOP
	if "%n%"=="0" echo 0 &amp;&amp; goto :eof
	if "%n%"=="1" echo %a% &amp;&amp; goto :eof
	set /a n = n - 1
	set /a swap = a + b
	set /a b = a
	set /a a = swap
	goto :LOOP

```実行してみましょう。
```dosbatch
C:\Users\kunst\Desktop>fib 0
0

C:\Users\kunst\Desktop>fib 1
1

C:\Users\kunst\Desktop>fib 10
55

C:\Users\kunst\Desktop>fib 20
6765

```<br/>
できあがり!<br/>
<br/>
<br/>

```dosbatch
C:\Users\kunst\Desktop>fib 50
-298632863

```ありゃりゃ……

</div>