c语言模拟实现栈的模板化

C语言模板化编程实战:从宏到泛型,实现类型安全与代码复用 在C语言开发中,宏(Macro)是实现代码复用的基础工具,它通过预处理器进行文本替换,能够减少重复代码。然而,简单的宏函数缺乏类型安全,容易引发副作用和调试困难。为了在保持C语言高性能的同时实现类型安全,开发者可以借助C11标准引入的泛型选择(_Generic)和基于头文件的代码生成模式,模拟出类似模板的编程范式。这种技术通过编译时类型分发和预处理代码生成,在嵌入式系统、操作系统内核和高性能计算等场景中,能够构建出类型安全的通用数据结构和算法库,显著提升代码的健壮性和可维护性。本文以动态数组为例,深入探讨了 阅读详情
       对于写过表达式解析的同学一定不会陌生,我们需要两个栈,一个是符号栈(char),一个是操作数栈(int).  经典的数据结构书中的栈,类型是定死了的。

所以能够实现一个栈,自己指定类型,想必编写接下来代码的心情要愉快的多。本实现过程采用宏定义,这样然接口看来就好像实现了模板化。这里有篇csdn的文章也是实现了模板化的,但是它采用的是预处理运算符## 实现的,及字符串化(stringification),具体链接:http://blog.youkuaiyun.com/kingofmiaomiao/article/details/2011195   (注意:字符串化也是属于宏的范畴)

下面给出,本人实现的编码,参考了一个名叫glu的开源项目中的array实现,在此表示感谢。

stack.h (这里的push, pop因为大家应该都是再熟悉不过了,就没有写日志了哈)

/**
 *该文件实现了对栈操作的模板化,在实现过程中参考了一个开源的glu项目
 *The file has template the operation about stack by referencing a opensource project 'glu'
 *@author daniel
 *@date 2011-09-19
 */
#ifndef _STACK_H
#define _STACK_H
#include <string.h>
#include <stdlib.h>

#define STACK_INIT_SIZE 50
#define STACK_ERROR -1

#define initStack(type,number) \
	stack_do_alloc(sizeof(type), number)
#define push(type,stack,data) \
	(stack_error_msg = stack_resize((stack), (stack)->num + 1), \
	stack_error_msg != STACK_ERROR ? \
	 *((type *)((stack)->space + (stack)->num++ * (stack)->obj_size)) = data : data)
#define getTop(type,stack) \
	((stack)->num ? *((type *)((stack)->space + ((stack)->num - 1) * (stack)->obj_size)) : *((type *)0))
#define pop(type,stack) \
	((stack)->num ? ((stack)->num--, *((type *)((stack)->space + (stack)->num * (stack)->obj_size))): *((type *)0))
#define getNum(stack)	\
	((stack)->num)
#define isEmpty(stack)	\
	(0 == (stack)->num)
#define clearStack(stack) \
	((stack)->num = 0, \
	 (void) memset((stack)->space, 0, (stack)->n_size * (stack)->obj_size))
#define freeStack(stack) \
	(FREE((stack)->space), \
	 FREE(stack))

#  define ALLOC(type, num)	\
    ((type *) malloc(sizeof(type) * (unsigned long) (num)))
#  define REALLOC(type, obj, num)	\
    ((type *) realloc((void *) (obj), sizeof(type) * (unsigned long) (num)))
#  define FREE(obj)		\
    ((obj) ? (free((void *) (obj)), (obj) = 0) : 0)
#  define NIL(type)		((type *) 0)

#ifndef MAX
#  define MAX(a,b)		((a) > (b) ? (a) : (b))
#endif

int stack_error_msg;

typedef struct{
	char *space; // the head point
	int num; // number of stack elements
	int n_size; // size of stack or says capability
 	int obj_size; // size of each stack object
} stack_t;

stack_t * stack_do_alloc(int, int);
int stack_resize(stack_t *stack, int newnum);

#endif

stack.c

#include "stack.h"

stack_t * stack_do_alloc(int size, int number){
	stack_t *stack;

	stack = ALLOC(stack_t, 1);
	if(NIL(stack_t) == stack)
		return NIL(stack_t);
	
	stack->num = 0;
	stack->n_size = MAX(number, STACK_INIT_SIZE);
	stack->obj_size = size;
	stack->space = ALLOC(char, stack->n_size * stack->obj_size);
	if(NIL(char) == stack->space)
		return NIL(stack_t);

	(void) memset(stack->space,0,stack->n_size * stack->obj_size);
	return stack;	
}

int stack_resize(stack_t *stack, int newsize){
	int old_size;
	char *newspace, *pos;

	if(stack->n_size > newsize)
		return 0;
	
	old_size = stack->n_size;
	stack->n_size = MAX(stack->n_size * 2, newsize);
	newspace = REALLOC(char, stack->space, stack->n_size * stack->obj_size);
	if(NIL(char) == newspace){
		stack->n_size = old_size;		
		return -1;
	}
	stack->space = newspace;
	
	pos = stack->space + old_size * stack->obj_size;
	(void) memset(pos, 0, (stack->n_size - old_size) * stack->obj_size);
	return 0;
}
测试代码:
#include "stack.h"
#include <stdio.h>

int main(){
	
	stack_t *a = initStack(int, 10);
	push(int, a, 123);
	printf("getTop:%d\n", getTop(int, a));
	pop(int, a);
	freeStack(a);
	return 0;
}






        
[Vector] 纯C语言用宏实现简单STL Vector 用宏在纯C中实现很好用的、与C++完全兼容的Vector。本质是malloc动态内存分配,经过宏的包装,可以在C和C++中使用相同方式调用。 阅读详情

相关推荐

C语言实现链式栈的模板

在C语言里面没有模板一说,这里通过用一些极为巧妙的方法来实现了类似于C++的模板功能,使得链式栈的数据可以通过实际需要的类型来决定

栈和队列的模拟实现(C语言版)

【代码】栈和队列的模拟实现(C语言版)

2301_80820096的博客 368

C语言链表、队列、栈C++模板化

附带高一凡版《算法与数据结构》文档,将链表、队列、栈C++模板化代码

C语言模拟实现栈和队列

栈的概念及结构:栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In FirstOut)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据也在栈顶。

qq_73874574的博客 388

一文搞懂【Linux 搭建 Dread Hunger 服务器】附本体及Docker部署集群方案

看直播发现了五花八门的开服器和版本,一时兴起按官方文档进行了搭建尝试,所以我的版本基于官方Stream2024.01.10更新的版本,也就是停服时的玩法,应该可以根据mod和补丁魔改成更那些开服器一样的版本,本文不做谈论,注重服务器搭建,毕竟8个人不可能在一个局域网里乱象:首先,我看了大量教程视频,一类是开服器的推广,另一类自建的基本采用Windows搭建,我觉得最离谱的是大部分教程都会教你买一台远程Windows虚拟机???

LHmine的博客 3985

保姆级教程:在Windows上用VS2019和OpenCV4.6搞定海康MV-EB435i RGBD相机图像采集

本文提供了一份详细的教程,指导如何在Windows环境下使用VS2019和OpenCV4.6配置海康MV-EB435i RGBD相机进行图像采集。从开发环境准备、SDK部署到代码移植和优化,涵盖了深度图与RGB图同步采集的实战技巧,帮助开发者快速上手工业级RGBD相机的应用开发。

weixin_28675557的博客 466

纯c语言模拟栈和队列(初学必看)

栈是一种特殊的线性表,在栈这个结构里,越先存进去的数据越难取出来。这个结构就像是一个只有一端有打开的容器,越先放进去的球越在底部,想要把底部的球拿出来,就必须先把前面的求拿出来。像这种”先进后出“的结构就是栈。对于栈来说,我们只能在表尾进行插入或者删除,表。

稻草人敲代码的博客 1157

Qwen3-Omni-30B-A3B-Instruct微调指南:如何打造专属智能博物官(附数据集)

本文详细介绍了如何对Qwen3-Omni-30B-A3B-Instruct模型进行微调,以打造专业的智能博物官。指南涵盖了从理解模型架构优势、构建高质量文博数据集,到使用LLaMA-Factory进行实战微调、效果评估与部署优化的完整流程,并提供了关键的环境配置与性能优化建议,帮助开发者在垂直领域高效定制专属AI助手。

weixin_29096377的博客 1143

C语言-栈模版

要实现逆波兰表达式+高精度字符串的计算器,栈必不可少 C语言缺少各种数据结构库,于是写了一个栈 这里的ElemType是栈中元素的类型,我要存放的是长度很大的字符串指针,所以用的是char* 别的情形下更改,即可实现各种类型的栈 #include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> #define stack_staIZE 500 typedef cha

wu58430的博客 325

macOS安装Cplex+yalmip

macOS安装Cplex+yalmip

DS 4248

VS Code ESP-IDF无法找到源文件、头文件波浪线解决

背景:想要编译小智AI项目,可以正常编译。但是一些头文件,例如#include <nvs.h>等无法找到。

Hot_Ant的博客 1489

C 栈模板及笔记

文章目录顺序栈链表栈进制转换括号匹配 顺序栈 #include <iostream> #include <cstdio> using namespace std; #define MAXSIZE 100 typedef int Status; typedef int Elem; typedef struct sqStack { int len; Elem *bas...

代码中枢:软件工程理论与实践的桥梁 577

告别黑盒:深入解析西部数据UFS芯片的44个SMART健康参数(附高通XBL读取源码)

本文深入解析西部数据UFS芯片的44个SMART健康参数,结合高通XBL启动加载层源码,提供了一套完整的健康状态诊断方法论。从SCSI命令层封装到数据结构映射,详细介绍了如何在高通平台早期启动阶段捕获UFS健康状态,帮助工程师实现预测性维护。

weixin_30600197的博客 427

C语言泛型编程实战:四种模板化方案与通用链表实现

泛型编程是一种编写与数据类型无关的通用代码的编程范式,其核心原理是通过抽象类型操作,实现算法和数据结构的复用。在C语言中,虽然缺乏原生模板支持,但通过宏、void*指针、函数指针和结构体封装等技术,可以模拟泛型特性,显著提升代码的复用性、安全性和可维护性。这种技术价值在开发基础库、算法组件和嵌入式中间件时尤为突出,能够减少代码冗余,降低维护成本。应用场景广泛,包括通用容器(如链表、动态数组)、排序搜索算法、数学函数库等。本文深入探讨了C语言实现模板化的四种主流方案:预处理器宏的文本替换、void*泛型指针的

weixin_42522552的博客 284

AI Agent Harness Engineering 开发效率工具:Prompt工程、调试与监控平台

随着AI Agent技术从原型探索走向企业级落地,开发者普遍面临Prompt迭代无版本管控、Agent执行黑盒无法定位错误、上线后无监控导致故障频发、多团队协作效率低下四大核心痛点,据2024年LLMOps行业报告显示,没有配套工具链的Agent开发团队平均迭代周期是有工具链团队的6倍,线上故障率高达23%,平均资源浪费超过60%。

小白菜的博客 425

快手NS sig3签名算法(2025年1月)

快手NS sig3签名算法(2025年1月)

sh_moranliunian的博客 3670

用两个栈模拟一个队列

思路: 让栈A提供入队功能,栈B提供出队功能。 入队列:栈A。 出队列:如果栈B不为空,直接弹出栈B的栈顶数据;如果栈B为空,则依次弹出栈A的数据,放入栈B中,再弹出栈B的栈顶数据。方法一:#include<iostream> #include<stack> #include<string> using namespace std;template<class T> struct MyQueu

小树学信奥 490

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

用C语言模拟面向对象

用C语言模拟面向对象 分类: C语言算法2013-09-22 14:15 180人阅读 评论(0) 收藏 举报 c语言继承面向对象宏类  这个代码是修改自lwoopc,截取其中一部分,然后添加一部分。 在VC6.0和gcc可编译,大家可以从程序代码中的"//文件开始部分"开始看 CTOR是构造,DTOR是析构 [cpp] view p

yapi916580075的专栏 663

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C++中的抽象数据类型(ADT)与栈的实现

在编程中,我们常常需要处理一些通用的概念,而不局限于具体的语言或实现细节。例如,“栈”是一种数据结构,它只允许在一端(称为栈顶)添加或删除元素。这种描述不涉及具体是用数组还是链表,也不关心存储的元素是什么类型。这种用通用方式描述数据类型的方式,就是抽象数据类型(ADT)。ADT关注的是“做什么”,而不是“怎么做”。它定义了数据的逻辑结构和允许的操作,将实现细节隐藏起来。公有接口描述操作,私有成员隐藏实现。用接口描述行为,用实现隐藏细节。C++类天然支持这种封装,使得我们可以构建出可靠、易维护的代码。

钢铁男儿 674

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一周拿下C语言:不玩虚的,只教真的

C语言虽被誉为编程“基石”,但无需陷入理论迷宫,核心在于用对方法、精准发力。一周突破的关键,是避开无效刷题和盲目记背,以“技巧赋能+靶向练习”为核心,聚焦可落地的方法

ney77的博客 325

揭秘C++量子态叠加模拟:如何用经典计算机实现量子并行性计算

掌握C++量子计算模拟核心技术,揭秘如何在经典计算机上实现量子态叠加与并行计算。涵盖线性代数模拟、量子门操作实现及多量子比特状态管理,适用于算法验证与教学实践。高效、可控、易于调试,是学习量子计算的理想方案,值得收藏。

PixelFlow的博客 743

我用C语言玩对象,框架化的模板模式

概念模板模式(Template Pattern)模式:属于行为型模式,对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现,但是整体处理/算法逻辑的框架是一致的。Template提...

不只会拍照的程序猿 262

毕业设计实战:模拟数据生成系统从Spring Boot开发到Web部署全流程

本文设计了一种基于Spring Boot的模拟数据生成系统,旨在解决科研、测试中真实数据获取难、隐私保护严、场景适配差等痛点。系统采用B/S架构,通过MySQL存储配置,实现数据自动构建与模板化生成两大核心功能。核心技术包括自定义XML解析动态生成数据库表、模板标签语言实现代码自动化生成。系统提供一站式解决方案,从实体管理到项目部署全流程覆盖,支持跨终端访问,具有开发效率高、扩展性强的特点。通过功能测试验证,系统能有效生成符合真实数据特征的模拟数据,满足无敏感信息、场景覆盖全的实际需求。

1480

C++栈模拟实现:从STL使用者到容器设计者的进阶之路

栈作为一种基础的后进先出(LIFO)数据结构,是理解内存管理、函数调用和算法设计的关键。其核心原理是通过限制数据访问顺序,在特定场景下实现高效操作。在C++工程实践中,标准模板库(STL)的std::stack提供了现成实现,但深入其底层机制能显著提升开发者对模板编程和容器设计的掌控力。通过模拟实现一个可配置底层容器(如deque、vector)的栈模板类,开发者能透彻理解异常安全、移动语义和泛型设计等高级概念。这种从使用到创造的实践,尤其适合希望夯实C++核心能力、应对技术面试或进行底层性能优化的工程师。

weixin_34059951的博客 376

Windows区域语言模拟终极指南:深度解析Locale Emulator的技术实现与应用场景

Locale Emulator是一款专业的Windows区域语言模拟工具,能够在不修改系统设置的前提下,为特定应用程序模拟不同的区域和语言环境。这款工具特别适合需要运行多语言软件、测试国际化应用或玩跨区域游戏的开发者和用户。 ## 📊 技术架构深度解析:Locale Emulator如何实现区域模拟 ### 核心模块分工与协作流程 Locale Emulator采用模块化设计,各组件协同工

gitblog_00836的博客 147

【C++】vector的使用和模拟实现

本篇文章介绍了vector的使用方法和模拟实现

分享学习经历和成果 811
上一篇: 数组名和数组名取地址的区别
下一篇: 关于c中volatile关键字(转贴)
wong_daniel
博客等级 码龄19年 37粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值