本节主要说程序中的栈函数栈的关系以及栈和递归算法的关系。

一、函数调用时的栈

1.程序调用时的栈是也就是平时所说的函数栈是数据结构的一种应用,函数调用栈一般是从搞地质向低地址增长的,栈顶为内存的低地址,栈底为内存的高地址。函数调用栈中存储的是数据的活动记录。活动记录是函数一些信息。如下如所所示:

2.假如有如下程序:

#include <stdio.h>
#include <stdlib.h> void fun(char* a)
{
char* b;
strcpy(b,a);
}
int main()
{
char a = '1';
fun(&a);
return 0;
}

那么在函数调用的过程中,函数栈的活动记录如下所示:

3.程序中的栈可以看做是顺序栈的一个应用,栈中保存了一个函数调用所需要的维护信息,包括函数参数,函数返回值地址,局部变量,函数调用上下文等。

4.具体的函数中的栈的实现请看另一篇博文:http://blog.csdn.net/cheyuxuan/article/details/9722463

二、程序中的栈

1.前一阶段在某实训机构做了一个所谓的项目时候,里面使用到了一个冒泡排序,但是排序的数据量很大,大约有6万个,程序的复杂度是O(n2),在程序运行一会后就会自动跳出,后来经过问大牛才知道这是因为栈溢出的原因。
2.程序在运行过程中,函数都是要被压入栈中的, 所以我们不断的调用函数,那么就会导致栈空间溢出,程序直接死掉。

3.造成栈溢出的原因通常有如下两点:①递归过深②局部数组过大,因为每一次递归都要调用函数,都要进行压栈的操作,所以这样会导致栈溢出,同时,如果我们定义的局部数组过大,数组也是在栈上分配空间的,那么也会造成栈上的空间不足,造成栈溢出。

三、程序中的栈的应用----递归调用

1.递归的算法是任何一门语言的基本功,但是理解起来其实也比较困难,这节先不说递归调用算法的实现,先来说一下递归和栈的关系。

2.例程:

#include <stdio.h>

void reverse(char* s)
{
if( (s != NULL) && (*s != '\0') )
{
reverse(s + 1); printf("%c", *s);
}
} int main()
{
reverse("12345"); printf("\n"); return 0;
}

程序打印的结果如下:

从程序大打印结果我们可以看出,我们实现了字符串"12345",最关键的是我们并没有使用我们惯用的for和count的方法。

解析:

我们从主函数调用reverse函数,向reverse函数传递的参数是字符串"12345"的首地址,然后进入子函数reverse,进行两个安全性的检测以后,我们再次调用reverse这个函数,这个时候向这个函数传递的是字符串"12345"的第二个元素的地址,依次类推,最后我们向reverse函数传递的是最后一个字符串的地址,这个时候程序中的栈被经历了5次reverse函数的压入,在第五次运行结束以后,栈中的值依次弹出,首先弹出的是第五个元素,然后以此类推。最后打印出我们上面的打印结果。

具体过程如下图所示:

程序在递归调用期间不断的向栈中压入每一次函数调用的记录,在递归调用结束后再从栈栈弹出每一次的记录,所以就打印出了我们看到的值。

四、总结

1.程序栈空间在本质上是一种顺序栈。

2.程序栈空间的访问是通过函数调用执行的。

3.程序栈空间仍然遵守后进先出的原则。

5.问题:①某实训机构的老师说程序的栈空间时从两侧增长的,我没有想懂,首先那那违背了栈的存储结构,其次同学早上和我说实际上栈的调度是CPU在控制的。

②程序中的栈空间,数据结构中的栈,还有真正的汇编硬件中的栈那个关系还需要深度学习,现在心里大概懂一点,但是无法形成一个整体的脉络。

C语言数据结构----栈与递归的更多相关文章

  1. C语言数据结构-栈的实现-初始化、销毁、长度、取栈顶元素、查找、入栈、出栈、显示操作

    1.数据结构-栈的实现-C语言 #define MAXSIZE 100 //栈的存储结构 typedef struct { int* base; //栈底指针 int* top; //栈顶指针 int ...

  2. C语言数据结构-栈

    一.栈的定义 栈(statck)这种数据结构在计算机中是相当出名的.栈中的数据是先进后出的(First In Last Out, FILO).栈只有一个出口,允许新增元素(只能在栈顶上增加). 移出元 ...

  3. C语言数据结构----栈的应用(程序的符号匹配检测)

    本节主要讲利用栈来实现一个程序中的成对出现的符号的检测,完成一个类似编译器的符号检测的功能,采用的是链式栈. 一.问题的提出以及解决方法 1.假定有下面一段程序: #include <stdio ...

  4. C语言数据结构----栈的定义及实现

    本节主要说的是数据结构中的栈的基本定义和实现的方式,其中实现的方式采用的是复用顺序表和单向链表的方式. 一.栈的基本定义 1.栈是一种特殊的线性表,只能从固定的方向进出,而且栈进出的基本原则是:先进栈 ...

  5. 数据结构——栈与递归(recursion)

    /* recursion.c */ /* 递归 */ #include <stdio.h> void interface(void); /* 斐波那契数列以及阶乘函数声明 */ long ...

  6. C语言数据结构栈

    #include<stdio.h>#include<stdlib.h>typedef struct Node{ int data; struct Node* pnext;}no ...

  7. 数据结构——栈(C语言实现)

    #include <stdio.h> #include <stdlib.h> #include<string.h> #include<malloc.h> ...

  8. C语言数据结构之栈:中缀表达式的计算

    *注:本人技术不咋的,就是拿代码出来和大家看看,代码漏洞百出,完全没有优化,主要看气质,是吧 学了数据结构——栈,当然少不了习题.习题中最难的也是最有意思的就是这个中缀表达式的计算了(可以算+-*/和 ...

  9. (js描述的)数据结构[栈结构](2)

    (js描述的)数据结构[栈结构](2) 一.什么是栈结构 1.一种受限制的线性结构,这种结构可以基于数组来实现. 2.可以抽象成一个容器,上面的是栈顶,底下的是栈底.所以仅允许对栈顶进行操作, 二.栈 ...

随机推荐

  1. 物理引擎简介——Cocos2d-x学习历程(十三)

    Box2D引擎简介 Box2D是与Cocos2d-x一起发布的一套开源物理引擎,也是Cocos2d-x游戏需要使用物理引擎时的首选.二者同样提供C++开发接口,所使用的坐标系也一致,因此Box2D与C ...

  2. MAC上使用maven打android的包,报错:No Android SDK path could be found. 解决办法

    对android工程运行mvn compile出现如下信息: No Android SDK path could be found. You may configure it in the pom u ...

  3. [LeetCode]题解(python):147-Insertion Sort List

    题目来源: https://leetcode.com/problems/insertion-sort-list/ 题意分析: 用插入排序排序一个链表. 题目思路: 这题没什么好说的,直接用插入排序就行 ...

  4. hl7 java 解析

    原文链接 http://blog.csdn.net/ycyangcai/article/details/6643784 Hl7引擎的目标主要是解决将数据按HL7协议的要求标准化,和标准业务的集成和不同 ...

  5. asp.net内置对象session和cookie

    1.各个机器的session对象不同,不同浏览器之间不通用(换个浏览器,是个新的session). 2.session状态对象起始于网页打开,终止于网页关闭,生命周期有限. 3.关闭浏览器/超时的情况 ...

  6. Android NOTE

    一些小的点就记在这里吧…… MultiDex打包时zip错误 我遇到的是 Execution failed for task ':excelSior:packageAllDebugClassesFor ...

  7. Java+Python+Jython环境变量配置

    一.Java 环境变量配置: 新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.7.0变量名:CLASSP ...

  8. cad画指定大小矩形

    指定基点后输入(@长度,宽度)回车 举例:如你要画个600*300的矩形 则输入@600,300回车

  9. android 用 XML 自定义边框(只上下边框有色)

    直接上代码: <?xml version="1.0" encoding="UTF-8"?> <layer-list xmlns:android ...

  10. Android 屏幕适配方式

    适配:即当前应用在相同的手机上面显示相同的效果.适配前需要首先确定当前手机所属像素密度类型(如:xhdpi.hdpi.mdpi等) 像素密度:每英寸上分布的像素点个数,单位(dpi,ppi),利用勾股 ...