最近在搞摄像头驱动,o()︿︶)o 唉,别提有多烦,一堆寄存器就有人受的了……特么这不是单片机的开发,这是内核驱动开发……

今天放松一下,我们来看看数据结构中的栈,这节的知识点可以说是数据结构中最容易上手的知识点了,其实比起链表,其实链表也有栈和队列的模型,链表的头插其实就是后进先出,链表的尾插其实就是先进先出,这不就是栈和队列吗,哈哈,不知道学习数据结构的时候有没有意识到这一点,但是栈和队列和链表还是有所区别的,我们来看看。

首先了解一下,什么是栈?

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

栈可以用来在函数调用的时候存储断点,做递归时要用到栈!最著名的实例便是汉诺塔,汉诺塔可以用递归来实现。

栈的生长方向是从高地址到低地址。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。

注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。严格说来,“栈帧底部”和“栈底”是不同的概念;ESP所指的栈帧顶部和系统栈的顶部是同一个位置。

在操作系统中,每一个线程都有一个栈,但是每个应用程序通常都只有一个堆,当然在为不同类型分配内存的时候使用多个堆并不是不可能。

那栈有什么特点?

1.  和堆一样存储在计算机 RAM
中。

2.  在栈上创建变量的时候会扩展,并且会自动回收。

3.  相比堆而言在栈上分配要快的多。

4.  用数据结构中的栈实现。

5.  存储局部数据,返回地址,用做参数传递。

6.  当用栈过多时可导致栈溢出(无穷次(大量的)的递归调用,或者大量的内存分配)。

7.  在栈上的数据可以直接访问(不是非要使用指针访问)。

8.  如果你在编译之前精确的知道你需要分配数据的大小并且不是太大的时候,可以使用栈。

9.  当你程序启动时决定栈的容量上限。

栈的算法主要由以下步骤构建而成:

.进栈(PUSH)算法

①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);

,指向进栈地址);

③S(TOP)=X,结束(X为新进栈的元素);

.退栈(POP)算法

①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈,空则下溢;不空则作②);

②X=S(TOP),(退栈后的元素赋给X):

,指向栈顶)。

说了这么多。以上是我对栈的理解,其实栈如果挖深一点,其实也是很深的,最精华的东西还是会跟指针结合到一起。先不研究太深的东西,我们还是直接上代码,看看到底是怎么回事,我的代码就依照栈的算法来实现:

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

int stack[20];
int max = 20;
int top = 0;			//设置栈	

//栈的初始化
void stack_init(void)
{
	memset(stack, 0, max);
	top = 0;
}

//判断栈是不是满了
int is_full(void)
{
	return top == max;
}
//入栈
int stack_push(int data)
{
	if(is_full())
	{
		return -1;
	}

	stack[top] = data;
	top ++;

	return 0;
}

//判断栈是否为空
int is_empty(void)
{
	return top == 0;
}

//出栈
int stack_pop(void)
{
	if(is_empty())
		return -1;

	top --;
	return stack[top];
}
//判断是不是在栈顶
int stack_top(void)
{
	return stack[top - 1];
}

int main(void)
{
	stack_init();  //初始化栈 

	int i;
	for(i = 0; i < 20; i++)
	{
		stack_push(i);  //将0-19这20个数入栈
	}

	printf("top = %d\n", stack_top());  //打印出栈顶的元素 

	for(i = 0; i < 20; i++)
	{
		printf("val = %d\n", stack_pop());  //出栈
	}
}

运行结果:

是最后进的,所以最先出,所以你会看到,我们的栈的生长方向即是从高处往低处走。

好了,今天打了下酱油,就到这里,准备早早睡觉!以后早早起床上班,才能早早的下班争取多点时间出来学习。下期播报:数据结构中的队列。

我的QQ空间博客: http://user.qzone.qq.com/826148759/appstore?via=QZ.DERECT.APPCENTER

浅析数据结构中栈与C实现的更多相关文章

  1. jvm 中内存的栈和数据结构中的栈的区别

    1.常见的数据结构:栈.队列.数组.链表和红黑树,java内存划分 2.JYM中的栈是先进先出,先入栈的先执行: 2.数据结构中的栈是先进后出,类似手枪的弹夹,先进入的子弹最后才发射: 3.数据结构中 ...

  2. Stack的三种含义(数据超过栈的大小,就发生stack overflow)

    非常典型的基础知识,转自http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈& ...

  3. 数据结构中的棧在C#中的实现

    数据结构中的棧在C#中的实现 一.大致学习 棧是一种面向表的数据结构,棧中的数据只能在标的某一短进行添加和删除操作,是一种典型的(LIFO)数据结构. 现实生活中的理解:自助餐厅的盘子堆,人们总是从顶 ...

  4. 使用JavaScript的数组实现数据结构中的队列与堆栈

    今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...

  5. JavaScript学习总结(二十一)——使用JavaScript的数组实现数据结构中的队列与堆栈

    今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...

  6. 面试题:java内存中的堆区和数据结构中的堆有什么区别

    java内存中的堆是一个  链表, 数据结构中的堆:就是一个栈

  7. [Data Structure] 数据结构中各种树

    数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 1. 二叉树 二叉树是数据结构中一种重要 ...

  8. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...

  9. 大数据全栈式开发语言 – Python

    前段时间,ThoughtWorks在深圳举办一次社区活动上,有一个演讲主题叫做“Fullstack JavaScript”,是关于用JavaScript进行前端.服务器端,甚至数据库(MongoDB) ...

随机推荐

  1. Texlive 更新命令

    设置repository tlmgr repository set http://mirror.hust.edu.cn/CTAN/systems/texlive/tlnet 上面的例子使用的是华中科技 ...

  2. 自定义一个View作为弹出对话框

    public void dialog(){ //获得布局对象 View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialo ...

  3. Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构

    转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789 前面几节中,都是通过java层调用 ...

  4. springMVC源码分析--动态样式ThemeResolver(二)

    在上一篇博客springMVC源码分析--动态样式ThemeResolver(一)中我们介绍了多样式ThemeResolver的使用方法,接下来我们对源码进行简单的分析一下. ThemeResolve ...

  5. 分析MapReduce执行过程+统计单词数例子

    MapReduce 运行的时候,会通过 Mapper 运行的任务读取 HDFS 中的数据文件,然后调用自己的方法,处理数据,最后输出.Reducer 任务会接收 Mapper 任务输出的数据,作为自己 ...

  6. Java继承时的初始化顺序

    Java程序在启动和运行时,需要首先完成初始化的工作.在涉及到继承.static成员变量等因素时,初始化的顺序就复杂起来.下面以一个例子说明继承时的Java初始化顺序. 例子: class Insec ...

  7. FORM触发器

     FORM级触发器 PRE-FORM该触发器是在用户双击功能后,进入form前 WHEN-NEW-FORM-INSTANCE该触发器是在用户一进入form时执行 WHEN-FORM-NAVIGAT ...

  8. JAVA之旅(三十三)——TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录

    JAVA之旅(三十三)--TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录 我们继续网络编程 一.TCP 说完UDP,我们就来说下我们应该重点掌握的TCP了 TCP传输 Soc ...

  9. [ExtJS5学习笔记]第二十二节 Extjs5中使用beforeLabelTpl配置给标签增加必填选项星号标志

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/39395753 官方例子:http://docs.sencha.com/extjs/5. ...

  10. Android项目开发填坑记-so文件引发的攻坚战

    故事的最初 我负责的项目A要求有播放在线视频的功能,当时从别人的聊天记录的一瞥中发现百度有相关的SDK,当时找到的是Baidu-T5Player-SDK-Android-1.4s,项目中Demo的so ...