原代码:
#include <stdio.h>
#include <stdlib.h>
int recurse(int x) {
int a[1<<15]; /* 4 * 2^15 = 64 KiB */
printf("x = %d. a at %p\n", x, a);
a[0] = (1<<14)-1;
a[a[0]] = x-1;
if (a[a[0]] == 0)
return -1;
return recurse(a[a[0]]) - 1;
}
int main(int argc, char *argv[]) {
int x = 100;
if (argc > 1)
x = atoi(argv[1]);
int v = recurse(x);
printf("x = %d. recurse(x) = %d\n", x, v);
return 0;
}
运行结果:
guest-IQlGHa@ubuntu:~/Desktop$ gcc -o a a.c
guest-IQlGHa@ubuntu:~/Desktop$ ./a
x = 100. a at 0xbfab80e0
x = 99. a at 0xbfa980c0
x = 98. a at 0xbfa780a0
x = 97. a at 0xbfa58080
x = 96. a at 0xbfa38060
x = 95. a at 0xbfa18040
x = 94. a at 0xbf9f8020
x = 93. a at 0xbf9d8000
x = 92. a at 0xbf9b7fe0
x = 91. a at 0xbf997fc0
x = 90. a at 0xbf977fa0
x = 89. a at 0xbf957f80
x = 88. a at 0xbf937f60
x = 87. a at 0xbf917f40
x = 86. a at 0xbf8f7f20
x = 85. a at 0xbf8d7f00
x = 84. a at 0xbf8b7ee0
x = 83. a at 0xbf897ec0
x = 82. a at 0xbf877ea0
x = 81. a at 0xbf857e80
x = 80. a at 0xbf837e60
x = 79. a at 0xbf817e40
x = 78. a at 0xbf7f7e20
x = 77. a at 0xbf7d7e00
x = 76. a at 0xbf7b7de0
x = 75. a at 0xbf797dc0
x = 74. a at 0xbf777da0
x = 73. a at 0xbf757d80
x = 72. a at 0xbf737d60
x = 71. a at 0xbf717d40
x = 70. a at 0xbf6f7d20
x = 69. a at 0xbf6d7d00
x = 68. a at 0xbf6b7ce0
x = 67. a at 0xbf697cc0
x = 66. a at 0xbf677ca0
x = 65. a at 0xbf657c80
x = 64. a at 0xbf637c60
x = 63. a at 0xbf617c40
x = 62. a at 0xbf5f7c20
x = 61. a at 0xbf5d7c00
x = 60. a at 0xbf5b7be0
x = 59. a at 0xbf597bc0
x = 58. a at 0xbf577ba0
x = 57. a at 0xbf557b80
x = 56. a at 0xbf537b60
x = 55. a at 0xbf517b40
x = 54. a at 0xbf4f7b20
x = 53. a at 0xbf4d7b00
x = 52. a at 0xbf4b7ae0
x = 51. a at 0xbf497ac0
x = 50. a at 0xbf477aa0
x = 49. a at 0xbf457a80
x = 48. a at 0xbf437a60
x = 47. a at 0xbf417a40
x = 46. a at 0xbf3f7a20
x = 45. a at 0xbf3d7a00
x = 44. a at 0xbf3b79e0
x = 43. a at 0xbf3979c0
x = 42. a at 0xbf3779a0
x = 41. a at 0xbf357980
x = 40. a at 0xbf337960
x = 39. a at 0xbf317940
x = 38. a at 0xbf2f7920
Segmentation fault (core dumped)
guest-IQlGHa@ubuntu:~/Desktop$ ./a 30
x = 30. a at 0xbf9db030
x = 29. a at 0xbf9bb010
x = 28. a at 0xbf99aff0
x = 27. a at 0xbf97afd0
x = 26. a at 0xbf95afb0
x = 25. a at 0xbf93af90
x = 24. a at 0xbf91af70
x = 23. a at 0xbf8faf50
x = 22. a at 0xbf8daf30
x = 21. a at 0xbf8baf10
x = 20. a at 0xbf89aef0
x = 19. a at 0xbf87aed0
x = 18. a at 0xbf85aeb0
x = 17. a at 0xbf83ae90
x = 16. a at 0xbf81ae70
x = 15. a at 0xbf7fae50
x = 14. a at 0xbf7dae30
x = 13. a at 0xbf7bae10
x = 12. a at 0xbf79adf0
x = 11. a at 0xbf77add0
x = 10. a at 0xbf75adb0
x = 9. a at 0xbf73ad90
x = 8. a at 0xbf71ad70
x = 7. a at 0xbf6fad50
x = 6. a at 0xbf6dad30
x = 5. a at 0xbf6bad10
x = 4. a at 0xbf69acf0
x = 3. a at 0xbf67acd0
x = 2. a at 0xbf65acb0
x = 1. a at 0xbf63ac90
x = 30. recurse(x) = -30
guest-IQlGHa@ubuntu:~/Desktop$
关于栈的溢出之前说过,函数调用时数据都储存在栈中,而递归函数是对函数的自身调用,就上面这个程序是对栈大小的测试,通过不停地对自身调用。总的来说,关于递归函数和栈,确实递归函数在运行是会大量占用栈的空间,很容易因为空间不足而发生错误,因此也限制了递归的次数,效率也不是很高,因此递归函数应该警慎使用。