当前位置: 首页 > news >正文

C语言栈的含义与栈数据操作代码详解!

引言:在本篇博客中,我们将学到数据结构——栈,讲到栈的含义与关于栈的数据操作代码可以在顺序表、双向链表以及单链表的基础上实现,而于本篇博客中,我们选择在顺序表的基础上实现

更多有关C语言和数据结构知识详解可前往个人主页:计信猫

目录

 

一,栈的含义

二,栈的结构体的定义

三,栈数据操作函数

1,栈的初始化

2,栈的销毁

3,入栈

 

4,出栈

5,取栈顶的数据

6,获取栈中数据的个数

7,判断栈是否为空

四,结语


一,栈的含义

        是一种特殊的线性表,只允许在表中固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端成栈底

压栈:栈的数据插入操作。

出栈:栈的数据删除操作。

        而因为特殊的数据插入和删除遵循LIFO(后进先出)的原则,使得可以被比作一个羽毛筒。(因为羽毛球里边的球都是从最上边开始使用的,类比于栈顶

二,栈的结构体的定义

        这次,我们仍然使用三文件操作法,分别创建stack.h、stack.c、test.c三个文件。

         因为前文提到,栈是一种特殊的顺序表,那么栈的定义应该和顺序表的定义方式极其相似,所以在stack.h中,我们如下定义栈:

//包含实现栈的操作函数所要用到的头文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int STDataType;
//创建栈结构体
typedef struct Stack
{STDataType* a;//动态数组int top;//栈顶的下一位int capacity;//数组总空间大小
}ST;

        可能大家会不理解top的含义,那么请看如下的图片讲解吧。

 

        如果里边没有元素的时候,那么此时top便指向数组中下标为零的地方。 

三,栈数据操作函数

        因为是在顺序表的基础上实现的,所以的数据操作函数与顺序表及其类似,甚至更简单,好好听吧,一定可以听懂!

1,栈的初始化

        对于栈的初始化其实就是将栈结构体中的指针类型赋值为NULL整型类型赋值为0就可以了,我们直接上代码:

// 初始化栈 
void StackInit(ST* ps)
{//断言判断栈不为NULLassert(ps);ps->a = NULL;ps->capacity = ps->top = 0;//top指向栈顶数据的下一位
}

2,栈的销毁

        在该函数中,我们所需要做的就是释放掉动态数组所开辟的空间,再将指针置空防止野指针的出现,最后将整型类型改为0就可以了。代码如下:

// 销毁栈 
void StackDestroy(ST* ps)
{free(ps->a);//释放动态数组空间ps->a = NULL;//防止野指针的出现ps->capacity = ps->top = 0;
}

3,入栈

        入栈顾名思义,就是在栈顶插入数据

        而在插入数据之前,我们就需要先判断动态数组的空间是否足够,不够我们就使用realloc函数进行空间大小的修改。判断空间代码如下:

//判断空间是否足够if (ps->top == ps->capacity)//top==capacity说明空间不够{int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//三目操作符STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);if (tmp==NULL)//防止空间申请失败{perror("realloc fail!");return;}ps->a = tmp;ps->capacity = newcapacity;}

        于此段代码之中,有两个非常巧妙之处:1,空间是否足够的判断:让我们仔细想想,当top变量等于capacity变量时是什么情况?

         对,就是如上图所示,当两者相等的时候,也就意味着整个动态数就只有一个空间以供使用了,而这时,我们就需要进行空间的动态开辟了。 

         2,三目操作符的使用:仔细想想,以下两种代码有什么不一样的呢?

代码一:
int newcapacity = ps->capacity * 2;
代码二:
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;

        其实答案十分简单,在我们对栈进行初始化的时候,我们将topcapacity变量都初始化为了0,那如果是代码一0*2就为0,则不就乱套了吗?所以我们便使用代码二用到了三目操作符来避免0*20的尴尬情况

        而之后的入栈函数就十分简单了,但千万别忘了要对top进行++处理!! 

// 入栈 
void StackPush(ST* ps, STDataType data)
{assert(ps);//判断空间是否足够if (ps->top == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);if (tmp==NULL){perror("realloc fail!");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = data;//top处加入新的元素ps->top++;//栈顶的移动
}

4,出栈

        对于出栈函数,其实我们所需要做的就是删除掉栈顶的元素,并且将栈顶向后移动一位。而对于栈顶元素的删除,我们也无需像链表一样使用free函数,我们只需要将top1即可,十分的简单。直接上代码!

// 出栈 
void StackPop(ST* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

5,取栈顶的数据

        因为栈顶是一个中及其特殊的位置,所以我们也就时不时会用到栈顶的数据,而这个函数就很好的帮我们解决了这个问题。

        在这个函数中,我们唯二需要注意的就是栈不可以为空指针,栈的数据个数不可以为零。代码走起!

// 获取栈顶元素 
STDataType StackTop(ST* ps)
{assert(ps);//栈不为空指针assert(ps->top > 0);//栈的数据个数不能为零STDataType tmp = ps->a[ps->top - 1];//top-1才为栈顶元素的下标return tmp;
}

6,获取栈中数据的个数

        这个函数是关于栈的数据操作函数中最简单的一个函数。栈中的数据个数不就是top的值吗,所以我们直接返回top就可以了。代码如下:

// 获取栈中有效元素个数 
int StackSize(ST* ps)
{assert(ps);return ps->top;
}

7,判断栈是否为空

        该函数比较特殊,它使用到的是布尔类型。如果栈为空,就返回true;反之则返回false。而对于是否为空的判断,我们只需要观察top是否为零就可以了。所以代码如下:

// 检测栈是否为空
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;//若top为零,则为true;反之则为false
}

四,结语

        这是有关数据结构中的讲解,是不是易如反掌呢?之后我也会接着更新数据结构中另一个知识点——队列的讲解。

        博客不仅是我记录所学习到的知识点的工具,也是我找到同样有学习编程爱好的人的朋友圈,希望我的博客可以对你有所帮助,也希望你可以留下你的鼓励,你的鼓励就是我最大的动力!!加油!

相关文章:

C语言栈的含义与栈数据操作代码详解!

引言&#xff1a;在本篇博客中&#xff0c;我们将学到数据结构——栈&#xff0c;讲到栈的含义与关于栈的数据操作代码。栈可以在顺序表、双向链表以及单链表的基础上实现&#xff0c;而于本篇博客中&#xff0c;我们选择在顺序表的基础上实现栈。 更多有关C语言和数据结构知识…...

数据库基础语法二

一、数据库 1、登陆数据库 2、创建数据库zoo 3、修改数据库zoo字符集为gbk 4、选择当前数据库为zoo 5、查看创建数据库zoo信息 6、删除数据库zoo mysql -uroot -p #登陆数据库 create database zoo; #创建数据库zoo alter database zoo character set gbk collate gbk_…...

数据库的一些知识点

在Sno between列上创建约束,要求Sno的值在18至22岁之间,约束名Sno_CK。请写出对应的完整性命名子句constraint Sno_CK primary key check and。 本题得分&#xff1a; 0分 正确答案&#xff1a; 填空1 : 学号填空2 : snobetween18and22 2.单选题 (12分) 下述SQL命令的短语中…...

[AutoSar]BSW_Com021单帧 首帧 流控帧 连续帧 详解

目录 关键词平台说明一、N_PDU和N_PCI二、单帧三、首帧四、流控帧五、连续帧六、case 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagnostic 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (…...

CSS学习笔记之中级教程(一)

1、CSS 布局 - display 属性 1.1 display 属性 display 属性是用于控制布局的最重要的 CSS 属性。 display 属性规定是否/如何显示元素。 每个 HTML 元素都有一个默认的 display 值&#xff0c;具体取决于它的元素类型。大多数元素的默认 display 值为 block 或 inline。 …...

Spring Cloud Alibaba 网关 Gateway 集成(7)

项目的源码地址 Spring Cloud Alibaba 工程搭建&#xff08;1&#xff09; Spring Cloud Alibaba 工程搭建连接数据库&#xff08;2&#xff09; Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用&#xff08;3&#xff09; Spring Cloud Alibaba Ribbo…...

低代码技术赋能未来乡村建设:创新与实践

引言 随着我国新型城镇化进程的推进&#xff0c;乡村建设正面临着前所未有的挑战。如何在有限的人力、物力、财力资源下&#xff0c;高效推动乡村建设&#xff0c;实现城乡一体化发展&#xff0c;成为当下亟待解决的问题。低代码技术作为一种创新性的解决方案&#xff0c;为未来…...

基于Springboot的房屋租赁管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的房屋租赁管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…...

跨平台移动应用开发指南:打造跨越iOS和Android的移动应用

跨平台移动应用开发已经成为许多开发者的首选&#xff0c;因为它可以节省时间、成本和精力&#xff0c;同时使得应用能够覆盖更广泛的用户群体。本指南将介绍跨平台移动应用开发的基本概念、流行的跨平台框架以及一些最佳实践&#xff0c;帮助您快速入门并打造出高质量的跨平台…...

QT+多线程编程

QT的多线程编程有两种 1、自定义类继承QThread 第一种是自定义一个类继承于QThread&#xff0c;重写run()方法来实现。然后当需要使用线程的时候你就新建一个自定义对象&#xff0c;然后调用start方法开始运行。 下面的例子是widget里面创建一个线程&#xff0c;然后调用sta…...

设计模式——迭代器模式(Iterator)

迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为设计模式&#xff0c;它使得我们能够顺序地访问一个聚合对象中的各个元素&#xff0c;而又不需要暴露该对象的内部表示。迭代器模式为遍历不同的聚合结构提供了一个统一的接口&#xff0c;使得客户端代码可以独立…...

在k8s中安装Grafana并对接Prometheus,实现k8s集群监控数据的展示

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Grafana&#xff1a;让数据说话的魔术师》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Grafana简介 2、Grafana的重要性与影响力 …...

【JavaScript】内置对象 - 数组对象 ③ ( 数组反转 - reverse 方法 | 数组排序 - sort 方法 | 自定义数组排序规则 )

文章目录 一、数组排序1、翻转数组元素 - reverse()2、数组元素排序 - sort() 默认从小到大排序3、数组元素排序 - sort() 自定义排序规则4、数组元素排序 - sort() 自定义降序排序简化写法 Array 数组对象参考文档 : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript…...

ctfshow web入门 php反序列化 web267--web270

web267 查看源代码发现这三个页面 然后发现登录页面直接admin/admin登录成功 然后看到了 ///backdoor/shell unserialize(base64_decode($_GET[code]))EXP <?php namespace yii\rest{class IndexAction{public $checkAccess;public $id;public function __construct(){…...

智慧公厕解决什么问题?实现了什么样的价值?

公共厕所一直是城市管理的难题&#xff0c;常常面临着卫生条件不佳、管理不善以及使用体验差等问题。为了解决这些困扰城市的难题&#xff0c;智慧公厕应运而生。智慧公厕不仅应用了信息化和数字化技术&#xff0c;还通过全方位的智能化应用&#xff0c;彻底改变了传统公厕的面…...

IATF16949认证是什么?

IATF16949认证是一项国际质量管理体系的认证标准&#xff0c;由国际汽车行业联合会&#xff08;IATF&#xff09;开发&#xff0c;旨在提高汽车行业的质量管理水平&#xff0c;满足客户对汽车部件和零部件的要求。该标准是在ISO/TS 16949标准的基础上&#xff0c;专门为汽车行业…...

【Vue2】关于response返回数据的错误小记

关于Vue2中response返回数据的一个错误小记 如图&#xff0c;在这里返回的时候&#xff0c;后端是通过List< String >返回的&#xff0c;response接收到的实际上是一个Array数组&#xff0c;但是赋值给searchedTaskList的时候&#xff0c;需要在.then包括的范围里面赋值给…...

深入理解C++构造函数和析构函数

目录标题 1. 构造函数默认构造函数参数化构造函数拷贝构造函数 2. 析构函数3. 构造函数和析构函数的使用场景自动资源管理防止资源泄露深拷贝和浅拷贝 4. C的类中必定有个构造函数吗&#xff1f;5. 总结 C中的构造函数和析构函数是类对象生命周期管理的重要组成部分。构造函数用…...

CMakeLists.txt语法规则:数学运算 math

一. 简介 前面几篇文章学习了 CMakeLists.txt语法中的一些常用变量&#xff0c;常用命令&#xff0c;双引号的作用。条件判断语句&#xff0c;循环语句等等。 本文简单学习一下 CMakeLists.txt语法中数学运算 match。 二. CMakeLists.txt语法规则&#xff1a;数学运算 math 在…...

图片无损压缩工具-VIKY

一、前言 Viky v3.4是一款功能强大的图片压缩工具&#xff0c;它能够提供高效的图片无损压缩服务。通过使用独特的压缩算法&#xff0c;该软件在显著减小图片文件大小的同时&#xff0c;还保持了图像的清晰度和色彩饱和度&#xff0c;确保了图像质量的优异表现。 二、软件特点…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...