搜索
bottom↓
回复: 1

C语言通用模式编程--栈的实现

[复制链接]

出0入0汤圆

发表于 2013-11-22 21:24:11 | 显示全部楼层 |阅读模式
最近在做XML解析器,中间需要用到二叉树,堆栈,所以写了一些通用算法

堆栈:支持任意数据类型的进栈和出栈(完成)
树:支持存储任意数据,支持任意节点的插入和删除操作(暂未完成)

先把通用栈代码给大家看看,欢迎使用,欢迎提意见
在不提供说明和例子,仅看头文件的话,我想大家用起来这个Stack,应该是没问题的^_^

============================== Header File =======================================
  1. //******************************************************************************
  2. //!
  3. //! \file   Stack.h
  4. //! \brief  Genernal Stack Model Interface.
  5. //!         You can use uniform stack API to manager different type of data
  6. //!         element.
  7. //! \author cedar
  8. //! \date   2013-11-22
  9. //!
  10. //! \license
  11. //!
  12. //! Copyright (c) 2013 Cedar MIT License
  13. //!
  14. //! Permission is hereby granted, free of charge, to any person obtaining a copy
  15. //! of this software and associated documentation files (the "Software"), to deal
  16. //! in the Software without restriction, including without limitation the rights to
  17. //! use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  18. //! the Software, and to permit persons to whom the Software is furnished to do so,
  19. //! subject to the following conditions:
  20. //!
  21. //! The above copyright notice and this permission notice shall be included in all
  22. //! copies or substantial portions of the Software.
  23. //!
  24. //! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. //! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. //! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. //! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. //! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. //! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  30. //! IN THE SOFTWARE.
  31. ///
  32. //******************************************************************************

  33. #ifndef __STACK_H__
  34. #define __STACK_H__

  35. #ifdef __cplusplus
  36. extern "C"
  37. {
  38. #endif

  39. //******************************************************************************
  40. //!                           CONFIGURE MACRO
  41. //******************************************************************************

  42. #define SYS_INTXX_T                         //!< Use stdint standard datatype
  43. #define USE_MEMORY_ALLOC                    //!< Use system malloc/free function


  44. #include <stdio.h>

  45. #ifdef SYS_INTXX_T
  46. #include <stdint.h>
  47. #else
  48. typedef unsigned char uint8_t;
  49. typedef unsigned int  uint32_t;
  50. #endif

  51. #ifdef USE_MEMORY_ALLOC
  52. #include <stdlib.h>
  53. #endif


  54. //******************************************************************************
  55. //!                           PUBLIC TYPE
  56. //******************************************************************************

  57. //! Stack Memory Model
  58. typedef struct Stack_t
  59. {
  60.     uint8_t* pBaseAddr;                    //!< Stack Base Address
  61.     uint8_t* pEndAddr;                     //!< Stack Top Address
  62.     uint8_t* pIndex;                       //!< Stack Data Index Pointer
  63.     uint32_t UnitSize;                     //!< Statck Element Size(Unit: Byte)
  64. }Stack_t;


  65. //******************************************************************************
  66. //!                           PUBLIC API
  67. //******************************************************************************
  68. #ifdef USE_MEMORY_ALLOC
  69. extern Stack_t* Stack_Create(uint32_t StackSize, uint32_t UnitSize);
  70. extern void Stack_Destory(Stack_t* pStack);
  71. #endif // USE_MEMORY_ALLOC
  72. extern int Stack_Init(Stack_t* pStack, void* pStackBaseAddr, uint32_t StackSize,
  73.         uint32_t UnitSize);
  74. extern int Stack_Pop(Stack_t* pStack, void* pElement);
  75. extern int Stack_Push(Stack_t* pStack, void* pElement);

  76. #ifdef __cplusplus
  77. }
  78. #endif

  79. #endif // __STACK_H__
复制代码
============================== Source Code =======================================
  1. #include "Stack.h"

  2. #ifdef USE_MEMORY_ALLOC
  3. //******************************************************************************************
  4. //
  5. //! \brief  Create An New Stack.
  6. //!
  7. //! \param  [in] StackSize is the size of stack.
  8. //! \param  [in] UnitSize is the size of base element.
  9. //! \retval The Pointer of new create stack.
  10. //! \note   -# If StackSize <= UnitSize or memory allocate failure, this function will return
  11. //!            with NULL pointer, So, Caller must check return pointer carefully.
  12. //!
  13. //! \note   -# You must enable USE_MEMORY_ALLOC macro and ensure your system have <stdlib.h>
  14. //!            Header file before use this function.
  15. //******************************************************************************************
  16. Stack_t* Stack_Create(uint32_t StackSize, uint32_t UnitSize)
  17. {
  18.     Stack_t*  pStack         = NULL;         //!< Stack Pointer
  19.     uint8_t*  pStackBaseAddr = NULL;         //!< Stack Memory Base Address

  20.     //! Check stack parameters.
  21.     if(StackSize <= UnitSize)
  22.     {
  23.         //! Error, exit now.
  24.         return (NULL);
  25.     }

  26.     //! Allocate Memory for pointer of new stack.
  27.     pStack = (Stack_t*) malloc(sizeof(Stack_t));
  28.     if(NULL == pStack)
  29.     {
  30.         //! Allocate Failure, exit now.
  31.         return (NULL);
  32.     }

  33.     //! Allocate memory for stack.
  34.     pStackBaseAddr = malloc(StackSize);
  35.     if(NULL == pStackBaseAddr)
  36.     {
  37.         //! Allocate Failure, exit now.
  38.         return (NULL);
  39.     }

  40.     //! Initialize General Stack.
  41.     Stack_Init(pStack, pStackBaseAddr, StackSize, UnitSize);

  42.     return (pStack);
  43. }

  44. //******************************************************************************************
  45. //
  46. //! \brief  Destory Stack
  47. //!  This function first release memory section, then reinit the stack pointer parameter.
  48. //!
  49. //! \param  [in] pStack is the pointer of valid stack.
  50. //! \retval None.
  51. //!
  52. //! \note   -# You must enable USE_MEMORY_ALLOC macro and ensure your system have <stdlib.h>
  53. //!            Header file before use this function.
  54. //
  55. //******************************************************************************************
  56. void Stack_Destory(Stack_t* pStack)
  57. {
  58.     //! Check stack parameters.
  59.     if(NULL == pStack || NULL == pStack->pBaseAddr)
  60.     {
  61.         return; //!< Failure
  62.     }

  63.     //! Free stack memory
  64.     free(pStack->pBaseAddr);

  65.     //! Reset stack parameters
  66.     pStack->pBaseAddr = NULL;
  67.     pStack->pEndAddr  = NULL;
  68.     pStack->pIndex    = NULL;
  69.     pStack->UnitSize  = NULL;

  70.     return;     //!< Success
  71. }
  72. #endif // USE_MEMORY_ALLOC

  73. //******************************************************************************************
  74. //
  75. //! \brief  Initialize an exist stack.
  76. //!
  77. //! \param  [in] pStack is the pointer of valid stack.
  78. //! \param  [in] pStackBaseAddr is the base address pre-alloc memory, such as array.
  79. //! \param  [in] StackSize is the size of stack.
  80. //! \param  [in] UnitSize is the size of base element.
  81. //! \retval 0 if initialize successfully, otherwise return -1.
  82. //!
  83. //! \note   -# If stack pointer invalid or memory allocate failure, this function will return
  84. //!            with NULL pointer, So, Caller must check return pointer carefully.
  85. //!
  86. //******************************************************************************************
  87. int Stack_Init(Stack_t* pStack, void* pStackBaseAddr, uint32_t StackSize, uint32_t UnitSize)
  88. {
  89.     //! Check stack parameters.
  90.     if(NULL == pStack || NULL == pStackBaseAddr || StackSize <= UnitSize)
  91.     {
  92.         //! Error, exit now.
  93.         return (-1);
  94.     }

  95.     //! Success, Initilize stack
  96.     pStack->pBaseAddr = (uint8_t*) pStackBaseAddr;
  97.     pStack->pEndAddr  = (uint8_t*) ((uint32_t)pStackBaseAddr + StackSize);
  98.     pStack->pIndex    = (uint8_t*) pStackBaseAddr;
  99.     pStack->UnitSize  = UnitSize;

  100.     return (0);

  101. }

  102. //******************************************************************************************
  103. //
  104. //! \brief  Pop an element from stack.
  105. //!
  106. //! \param  [in]  pStack is the pointer of valid stack.
  107. //! \param  [out] pElement is the address of memory that store the pop element.
  108. //!
  109. //! \retval 0 if initialize successfully, otherwise return -1.
  110. //
  111. //******************************************************************************************
  112. int Stack_Pop(Stack_t* pStack, void* pElement)
  113. {
  114.     uint8_t * _pElement = (uint8_t *)pElement;
  115.     int i = 0;

  116.     //! Check stack parameters.
  117.     if(NULL == pStack || NULL == pElement)
  118.     {
  119.         //! Error, exit now.
  120.         return (-1);
  121.     }

  122.     //! UnderFlow ?
  123.     if(pStack->pIndex < pStack->pBaseAddr + pStack->UnitSize)
  124.     {
  125.         //! Error, Stack is empty!
  126.         return (-1);
  127.     }

  128.     //! Move Stack Pointer
  129.     pStack->pIndex = pStack->pIndex - pStack->UnitSize;

  130.     //! Copy Data
  131.     for(i = 0; i < pStack->UnitSize; i++)
  132.     {
  133.         *_pElement++ = *(pStack->pIndex + i);
  134.     }

  135.     return (0);
  136. }

  137. //******************************************************************************************
  138. //
  139. //! \brief  Push an element into stack.
  140. //!
  141. //! \param  [in] pStack is the pointer of valid stack.
  142. //! \param  [in] pElement is data element you want to push.
  143. //!
  144. //! \retval 0 if initialize successfully, otherwise return -1.
  145. //
  146. //******************************************************************************************
  147. int Stack_Push(Stack_t* pStack, void* pElement)
  148. {
  149.     uint8_t * _pElement = (uint8_t *)pElement;
  150.     int i = 0;

  151.     //! Check stack parameters.
  152.     if(NULL == pStack || NULL == pElement)
  153.     {
  154.         //! Error, exit now.
  155.         return (-1);
  156.     }

  157.     //! Overflow ?
  158.     if(pStack->pIndex + pStack->UnitSize > pStack->pEndAddr)
  159.     {
  160.         return (-1);
  161.     }

  162.     //! Copy Data
  163.     for(i = 0; i < pStack->UnitSize; i++)
  164.     {
  165.          *(pStack->pIndex++) = *_pElement++;
  166.     }

  167.     return (0);
  168. }

复制代码
注:
1: 最新代码,请参考https://github.com/cedar-renjun/General_Programming_Stack/
2: BinTree在进行中,会分享给大家

出0入0汤圆

发表于 2013-11-22 21:32:51 | 显示全部楼层
话说你的XML语言做脚语言吗?然后下面你自己再做个XML解析器,这样配多能配置一些参数啥的;如果做过程控制,效率很低吧。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 02:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表