今天看見朋友貼了一個入門的程式作業:「輸入 5 則輸出 12345 ,輸入 9 則輸出 123456789。」 大家第一個想到的解法應該是迴圈了,基本上也是用迴圈解會比較合適:
1 2 3 4 5 6 7 8 9 10
| #include <stdlib.h> #include <stdio.h> int main() { int i, t; scanf("%d", &t); for(i = 1; i <= t; i++) { printf("%d", i); } return 0; }
|
這個寫法如果寫錯,大概要去面壁了。當然,程式本來就有很多種寫法,撇除一些比較骯髒的寫法,如 if-else 搭配 printf,我們可以用遞迴來解,寫成副程式進行遞迴是最基本的寫法之一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<stdio.h> #include<stdlib.h>
int go(int n) { if(n == 1) { return 1; } else { int x = go(n-1); printf("%d", x); return x+1; } }
int main(int argc, char const **argv) { int n; scanf("%d", &n); printf("%d", go(n)); return 0; }
|
似乎有點多,如果我們能不寫副程式而實現遞迴呢?沒錯,直接遞迴 main() 也是一種作法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<stdio.h> #include<stdlib.h>
int main(int argc, char **argv) { int n, result; n = atoi(argv[1]); if(n == 1) { result = 1; } else { char buffer[16]; char *pt = buffer; char **pt2 = &pt - 1; sprintf(buffer, "%d", n-1); result = main(2, pt2) + 1; } printf("%d", result); return result; }
|
若是用 Static 變數則可以更簡化:
1 2 3 4 5 6 7 8 9 10 11
| #include<stdio.h> #include<stdlib.h>
int main(int argc, char **argv) { static int n = 0; if(++n && atoi(argv[1])) { printf("%d", n); return main(2, argv); } return 0; }
|
筆者在帶大學計概課程的時候是這樣寫的:
1 2 3 4 5
| #include <stdio.h> int main(int argc, char **argv) { printf("%d", argc-1); if(argc-1 < atoi(argv[1])) return main(++argc, argv); }
|
算是複習一下遞迴的概念與寫法,程式有點髒請見諒。不過,寫了這樣一篇遞迴文,還是老話一句: 「遞迴只應天上有,凡人該當用迴圈」。