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

C++与C语言实现Stack的对比分析

        面向对象编程有三大特性:封装、继承和多态。通过下面C和C++实现Stack的代码对比,我们可以初步了解封装的概念。

目录

一、主要差异对比

1、封装性体现

2、语法便利性

3、代码组织

二、C语言实现Stack分析

1、数据结构定义

2、核心函数实现

初始化函数

销毁函数

压栈操作

其他操作

3、C实现特点

三、C++实现Stack分析

1、类定义

2、核心成员函数实现

初始化函数

压栈操作

其他操作

四、主要区别分析

1、封装性

C++实现:

C语言实现:

2、语法便利性

C++优势:

3、代码组织

C++:

C:

五、实现思路详解

C语言实现思路

C++实现思路

六、两种实现的对比总结

七、深入理解封装

八、总结


一、主要差异对比

1、封装性体现

  • C++实现:将数据和相关操作函数都封装在类内部,通过publicprivate访问限定符进行访问控制

    • 数据成员(_a_capacity_top)设为private,外部无法直接访问和修改

    • 操作接口(PushPopTop等)设为public,作为类的外部接口

    • 封装本质是一种更严格、更规范的管理方式,避免了数据被随意修改的风险

  • C实现:数据和函数分离,结构体成员完全公开,可以直接访问和修改

2、语法便利性

  • this指针:C++成员函数隐式传递this指针,调用时不需要显式传递对象地址

  • 缺省参数:如Init(int n = 4)可以简化初始化调用

  • 类型系统:不需要typedef,直接使用类名作为类型

  • 命名空间:使用std命名空间避免命名冲突

3、代码组织

  • C++:相关数据和操作集中在一个类中,结构更清晰

  • C:数据和操作分离,需要通过指针显式传递结构体


二、C语言实现Stack分析

1、数据结构定义

typedef int STDataType;
typedef struct Stack {STDataType* a;      // 动态数组指针int top;            // 栈顶指针int capacity;       // 栈容量
} ST;

2、核心函数实现

初始化函数

void STInit(ST* ps) {assert(ps);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}
  • 接收Stack结构体指针

  • 将数组指针初始化为NULL,top和capacity设为0

销毁函数

void STDestroy(ST* ps) {assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}
  • 释放动态分配的内存

  • 重置所有成员变量

压栈操作

void STPush(ST* ps, STDataType x) {assert(ps);// 检查并扩容if (ps->top == ps->capacity) {int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));if (tmp == NULL) {perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
  • 检查容量不足时进行扩容

  • 初始容量为0时分配4个元素空间,否则容量翻倍

  • 将元素放入栈顶并更新top指针

其他操作

bool STEmpty(ST* ps);       // 判断栈是否为空
void STPop(ST* ps);         // 弹出栈顶元素
STDataType STTop(ST* ps);   // 获取栈顶元素
int STSize(ST* ps);         // 获取栈大小

3、C实现特点

  • 数据和操作分离

  • 每次操作都需要传递Stack指针

  • 结构体成员可以直接访问和修改

  • 需要手动管理内存


三、C++实现Stack分析

1、类定义

class Stack {
public:// 成员函数void Init(int n = 4);   // 初始化,带默认参数void Push(STDataType x);void Pop();bool Empty();int Top();void Destroy();private:// 成员变量STDataType* _a;size_t _capacity;size_t _top;
};

2、核心成员函数实现

初始化函数

void Init(int n = 4) {_a = (STDataType*)malloc(sizeof(STDataType) * n);if (nullptr == _a) {perror("malloc申请空间失败");return;}_capacity = n;_top = 0;
}
  • 使用默认参数简化调用

  • 直接访问成员变量(不需要传递对象指针)

压栈操作

void Push(STDataType x) {if (_top == _capacity) {int newcapacity = _capacity * 2;STDataType* tmp = (STDataType*)realloc(_a, newcapacity * sizeof(STDataType));if (tmp == NULL) {perror("realloc fail");return;}_a = tmp;_capacity = newcapacity;}_a[_top++] = x;
}
  • 扩容逻辑与C版本相同

  • 直接访问成员变量,代码更简洁

其他操作

void Pop() { assert(_top > 0); --_top; }
bool Empty() { return _top == 0; }
int Top() { assert(_top > 0); return _a[_top - 1]; }
void Destroy() { free(_a); _a = nullptr; _top = _capacity = 0; }

四、主要区别分析

1、封装性

C++实现

  • 将数据和操作数据的函数都封装在类内部

  • 使用访问限定符(public/private)控制访问权限

  • 数据成员通常设为private,防止外部直接修改

  • 提供公共接口(public方法)来操作数据

C语言实现

  • 数据和函数分离

  • 结构体成员可以直接访问和修改

  • 需要通过函数参数显式传递结构体指针

2、语法便利性

C++优势

  • 缺省参数Init(int n = 4)可以省略参数调用

  • this指针:成员函数自动获取当前对象指针,无需显式传递

  • 作用域解析:类名直接作为类型名,无需typedef

  • 命名空间:使用namespace避免命名冲突

3、代码组织

C++

  • 相关数据和函数组织在一个类中

  • 更符合"高内聚"的设计原则

  • 代码可读性和维护性更好

C

  • 数据和函数分离

  • 需要手动管理数据和函数的关系

  • 容易产生命名冲突


五、实现思路详解

C语言实现思路

  1. 数据结构定义

    • 使用结构体ST存储栈的数组指针、栈顶位置和容量

    • typedef定义栈元素类型,便于修改

  2. 函数设计

    • 每个操作函数都需要显式接收栈结构体指针

    • 使用断言(assert)检查指针有效性

    • 动态内存管理完全手动控制

  3. 使用方式

    • 必须先声明结构体变量

    • 每个操作都需要传递结构体地址

    • 需要显式初始化和销毁

C++实现思路

  1. 类设计

    • 将数据和操作封装在Stack类中

    • 成员变量设为private保护数据

    • 成员函数提供操作接口

  2. 自动关联

    • 成员函数自动关联到对象实例

    • 通过this指针隐式访问成员数据

    • 无需显式传递对象指针

  3. 资源管理

    • 仍使用手动内存管理(后续可改进为RAII)

    • 提供完整的初始化、销毁接口

  4. 使用便利性

    • 对象创建后直接调用方法

    • 方法调用更直观简洁

    • 缺省参数简化常见用例


六、两种实现的对比总结

特性C实现C++实现
数据与操作分离绑定在类中
访问控制无,可直接访问所有成员通过访问限定符控制
对象传递需要显式传递指针隐式this指针传递
类型定义需要typedef类名即类型
初始化需要单独调用初始化函数可带默认参数
内存管理手动手动(后续可用构造函数/析构函数改进)
代码组织分散集中

七、深入理解封装

封装不仅仅是把数据和函数放在一起,更重要的是:

  1. 访问控制:通过public/private限制对内部数据的直接访问

  2. 接口抽象:对外提供简洁的操作接口,隐藏实现细节

  3. 数据保护:防止外部代码随意修改内部状态,保证数据一致性

  4. 实现隔离:内部实现变更不影响外部代码

        在这个Stack实现中,C++版本通过类机制实现了基本的封装,但还只是封装的初级阶段。后续可以进一步改进:

  1. 使用构造函数和析构函数自动管理资源(RAII)

  2. 添加const成员函数保证不修改对象状态

  3. 考虑异常安全

  4. 实现拷贝控制和移动语义


八、总结

通过对比可以看出:

  1. C++的类机制提供了更好的封装性,这是最核心的区别

  2. C++语法提供了许多便利特性,简化了代码编写

  3. 当前实现中,底层逻辑和算法基本相同,主要区别在组织方式

  4. 这只是C++封装的初步展示,后续还有更多强大特性

        随着深入学习,特别是了解STL中的stack实现后,会更能体会C++的强大之处。STL stack采用适配器模式,基于deque/list/vector等容器实现,展现了更高层次的抽象和设计。

http://www.lryc.cn/news/612518.html

相关文章:

  • 如何快速翻译PPT中的文字(或简繁体转换)
  • PI 思维升级 解密电容器的选择与布局策略,带您追求极致平坦的电源阻抗
  • 【VTK】绘制圆锥进行简单的几何渲染
  • 图论(邻接表)DFS
  • AI领域的三箭齐发之夜 - genie3,gpt-oss, Opus 4.1
  • go与grpc
  • 【软考系统架构设计师备考笔记5】 - 专业英语
  • Xcode 26 如何在创建的 App 包中添加特定的目录
  • Linux——静态网络,创建用户
  • 基于PHP的快递管理系统的设计与实现
  • android10~16变更一览和开发者兼容应对
  • css优化、提升性能方法都有哪些?
  • React:生命周期
  • antd组件select下拉数据分页加载
  • LeetCode 分类刷题:611. 有效三角形的个数
  • 【前端】Vite中import.meta功能详解
  • 深度修改elementUI样式思路
  • 《Day2-PyTorch Tensor 从入门到实践:核心操作与避坑指南》
  • 磁悬浮转子变转速工况下的振动抑制全解析
  • Conditional Modeling Based Automatic Video Summarization
  • 云平台托管集群:EKS、GKE、AKS 深度解析与选型指南-第二章
  • [Python 基础课程]猜数字游戏
  • HIVE 窗口函数处理重复数据
  • 【C/C++】形参、实参相关内容整理
  • GISBox中OSGB数据转3DTiles格式指南
  • 开源流媒体服务器ZLMediaKit 的Java Api实现的Java版ZLMediaKit流媒体服务器-二开视频对话
  • java 之 继承
  • 【Java】HashMap的key可以为null吗?如何存储的?
  • JavaScript 基础语法
  • TDengine IDMP 背后的技术三问:目录、标准与情景