当前位置: 首页 > 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.dtcms.com/a/318270.html

相关文章:

  • sqli-labs通关笔记-第34关POST宽字符注入(单引号闭合 手工注入+脚本注入两种方法)
  • Verilog 仿真问题:打拍失败
  • FPGA学习笔记——VGA简介
  • Excel单元格设置下拉框、选项背景
  • 20250806给PRO-RK3566开发板在Buildroot系统下扩大rootfs分区2GB
  • 实习文档背诵
  • 解决Cloudflare人机验证加载异常:从常规排查到hosts配置优化
  • 【软件介绍】RVC本地部署使用方法
  • Linux基础命令详解手册
  • css怪异模式(Quirks Mode)和标准模式(Standards Mode)最明显的区别
  • 【CVPR2025】Mr.DETR: 通过多路线训练机制改进DETR,并进行“one to one”和“one to many”的预测
  • pytorch安装
  • ​​MCU程序的存储方式与存储区域大小要求​
  • c++ template in .h and .cpp
  • RocketMQ和Kafka一样有重平衡的问题吗?
  • 机器学习——朴素贝叶斯
  • Java面试题和答案大全
  • Web 端 AI 图像生成技术的应用与创新:虚拟背景与创意图像合成
  • Session 和 JWT(JSON Web Token)
  • [AI]从零开始的SDXL LORA训练教程
  • 机器视觉的智能手表贴合应用
  • Android 之 ViewBinding 实现更安全、高效的视图绑定
  • envFrom 是一个 列表类型字段bug
  • W3D引擎游戏开发----从入门到精通【22】
  • 《聚氨酯垫性能优化在超薄晶圆研磨中对 TTV 的保障技术》
  • 小实验--震动点灯
  • 昇思+昇腾开发板+DeepSeek模型推理和性能优化
  • Python实现信号小波分解与重构
  • 【CUDA】C2 矩阵计算
  • 大数据之Flume