算法竞赛入门经典_4.3_递归
来源:互联网 发布:unity3d js教程 编辑:程序博客网 时间:2024/05/21 23:52
看代码
#include <stdio.h>int f(int n){ return n == 0?1:f(n-1)*n;}int main(){ printf("%d\n", f(5)); return 0;}
上面f函数使用了递归,递归由两部分组成,一是递归头,二是递归体。
我们使用gcc调试工具
H:\编程书籍学习\算法竞赛入门经典2代码\算法入门经典第四章>b f'b' 不是内部或外部命令,也不是可运行的程序或批处理文件。H:\编程书籍学习\算法竞赛入门经典2代码\算法入门经典第四章>gdb a.exeGNU gdb (GDB) 7.4Copyright (C) 2012 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "i686-pc-mingw32".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from H:\编程书籍学习\算法竞赛入门经典2代码\算法入门经典第四章\a.exe...done.(gdb) l1 #include <stdio.h>23 int f(int n){4 return n == 0?1:f(n-1)*n;5 }6 int main()7 {8 printf("%d\n", f(5));9 return 0;10 }(gdb) lLine number 11 out of range; 4.3.1_递归阶乘.c has 10 lines.(gdb) b fBreakpoint 1 at 0x4013bd: file 4.3.1_.c, line 4.(gdb) sThe program is not being run.(gdb) rStarting program: H:\\2\\a.exe[New Thread 3640.0x2420]Breakpoint 1, f (n=5) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) sBreakpoint 1, f (n=4) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) sBreakpoint 1, f (n=3) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) sBreakpoint 1, f (n=2) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) sBreakpoint 1, f (n=1) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) sBreakpoint 1, f (n=0) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) s5 }
可以直接使用b f给函数设置断点,断点将设置在函数首部。使用s 进行单步执行,r运行
(gdb) bt#0 f (n=5) at 4.3.1_递归阶乘.c:4#1 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) sBreakpoint 1, f (n=4) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) bt#0 f (n=4) at 4.3.1_递归阶乘.c:4#1 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#2 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) sBreakpoint 1, f (n=3) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) bt#0 f (n=3) at 4.3.1_递归阶乘.c:4#1 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#3 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) sBreakpoint 1, f (n=2) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) bt#0 f (n=2) at 4.3.1_递归阶乘.c:4#1 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#4 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) sBreakpoint 1, f (n=1) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) bt#0 f (n=1) at 4.3.1_递归阶乘.c:4#1 0x004013cf in f (n=2) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#4 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#5 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) sBreakpoint 1, f (n=0) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;(gdb) bt#0 f (n=0) at 4.3.1_递归阶乘.c:4#1 0x004013cf in f (n=1) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=2) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#4 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#5 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#6 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }(gdb) bt#0 f (n=0) at 4.3.1_递归阶乘.c:5#1 0x004013cf in f (n=1) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=2) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#4 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#5 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#6 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }(gdb) bt#0 f (n=1) at 4.3.1_递归阶乘.c:5#1 0x004013cf in f (n=2) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#4 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#5 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }(gdb) bt#0 f (n=2) at 4.3.1_递归阶乘.c:5#1 0x004013cf in f (n=3) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#3 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#4 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }(gdb) bt#0 f (n=3) at 4.3.1_递归阶乘.c:5#1 0x004013cf in f (n=4) at 4.3.1_递归阶乘.c:4#2 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#3 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }(gdb) bt#0 f (n=4) at 4.3.1_递归阶乘.c:5#1 0x004013cf in f (n=5) at 4.3.1_递归阶乘.c:4#2 0x004013f6 in main () at 4.3.1_递归阶乘.c:8(gdb) s5 }
使用bt查看调用栈,很容易理解递归调用的关系了,
注:由于使用了调用栈,c语言支持递归,调用自己和调用其他函数,并没有本质上的不同
在这里,我们把主函数中的5改成1000000,gdb运行之后显示如下
(gdb) rStarting program: H:\\2\\a.exe[New Thread 4372.0x1e78]Program received signal SIGSEGV, Segmentation fault.0x004013c7 in f (n=1899934856) at 4.3.1_递归阶乘.c:44 return n == 0?1:f(n-1)*n;
Segmentation fault段错误。什么原因呢?
H:\编程书籍学习\算法竞赛入门经典2代码\算法入门经典第四章>size a.exe text data bss dec hex filename 23448 1324 2608 27380 6af4 a.exe
我们首先使用q退出刚才的gbd,使用size命令得到可执行文件中的各个段的大小
其中text为正文段,data为数据段,bss段,总大小是27380,。
注:正文段用于存储指令,数据段用来存储已初始化的全局变量,
bss段用于存储未赋值的全局变量和所需的空间,所以每次递归调用都需要
调用栈里面的栈帧,而当越界了,就是栈溢出
阅读全文
0 0
- 算法竞赛入门经典_4.3_递归
- 算法竞赛入门经典_4.1_判定素数_组合数
- 算法竞赛入门经典_4.2_函数调用和参数_gcc调试器的使用
- 算法竞赛_入门经典_刘汝佳__(1)
- 算法竞赛_入门经典_刘汝佳__(2)
- 算法竞赛入门经典
- 算法竞赛入门经典
- 算法竞赛入门经典_1.5_习题练习
- 算法竞赛入门经典课后习题3
- 算法竞赛入门经典习题3-2
- 算法竞赛入门经典---函数部分3
- 算法竞赛入门经典习题3-5
- 算法竞赛入门经典第3章
- 算法竞赛入门经典_2.4_算法竞赛中的输入输出框架
- 算法竞赛入门经典_3.1_数组_逆序输出_开灯问题
- 算法竞赛入门经典心得
- 《算法竞赛入门经典》勘误表
- 算法竞赛入门经典读书笔记
- Java字节码运行浅析
- linux之旅_linux是什么
- 算法竞赛入门经典_4.2_函数调用和参数_gcc调试器的使用
- greendao的demo
- IT解决_win10无法启动vc6++中文版问题
- 算法竞赛入门经典_4.3_递归
- IT解决方案_如何挑选一台适合自己的电脑
- Android SDK可用服务器代理设置
- 算法竞赛入门经典_5 c++与STL入门
- 一些动画教程
- windows下一些常用的dos命令
- 大学生创业基础
- 算法oj_q3_奇偶分离
- unity入门