一种c语言利用面向对象思想编程示例

      以下这段C语言代码体现了一种模拟面向对象编程思想的方式。在C++等真正的面向对象编程语言中,可以使用类(class)和对象(object)来直接实现封装、继承和多态等特性。然而在C语言中,由于没有内置的面向对象机制,程序员通常通过结构体(struct)结合函数指针的方式来模拟面向对象设计。

在这段代码中:

  • Queue_Pro 结构体代表了队列这一“对象”的属性(数据成员)。
  • Queue_Ops 结构体则扮演了方法集的角色,它包含了一系列指向操作队列相关功能的函数指针,模拟了面向对象中的方法或者成员函数。

当需要对队列进行操作时,通过调用queue_Ops中的函数指针来间接执行相应的操作,这样就实现了类似于面向对象中的消息传递机制——即通过对象调用其方法。

整体上看,尽管C语言本身不支持面向对象编程,但通过这种巧妙的设计和组织方式,可以在一定程度上实现面向对象编程的设计思路和优点,如封装性、模块化等。

首先给出代码:

queue.h

#ifndef _QUEUE_H_
#define _QUEUE_H_

#include <stdint.h>
/* 对象变量 */
typedef struct
{
    int32_t capacity;  //队列容量
    int32_t head;
    int32_t tail;
    int32_t size;  //队列缓存长度

} Queue_Pro;

/* 对象方法 */
typedef struct
{
    void (*Create)(Queue_Pro *self,uint32_t size);  //创建 初始化
    int8_t (*Enqueue)(Queue_Pro *self);  //进队列
    int8_t (*Dequeue)( Queue_Pro *self);  //出队列
    void (*SetEmpty)( Queue_Pro *self);   //清空
    int8_t (*IsEmpty)( Queue_Pro *self);  //

} Queue_Ops;

extern const Queue_Ops queue_Ops;




#endif


queue.c 

#include "queue.h"

static void Create(Queue_Pro *self, uint32_t size)
{
    self->capacity = size;
    self->head = 0;
    self->tail = 0;
    self->size =0;
}

static int8_t Enqueue(Queue_Pro *self)
{
    if (self->size == self->capacity) {
        // printf("队列已满,无法入队\n");
        return 0;
    }
    if (self->tail >= self->capacity)
        self->tail = 0;
    self->size++;

    return 1;
}

static int8_t Dequeue(Queue_Pro *self)
{
    if (self->size == 0) {
        // printf("队列为空,无法出队\n");
        return 0;
    }
    if (self->head >= self->capacity)
        self->head = 0;
    self->size--;

    return 1;
}

static void SetEmpty(Queue_Pro *self)
{
    self->head = 0;
    self->tail = 0;
    self->size = 0;
}

static int8_t IsEmpty(Queue_Pro *self)
{
    return (self->size == 0);
}

const Queue_Ops queue_Ops = {
    .Create = &Create,
    .Enqueue = &Enqueue,
    .Dequeue = &Dequeue,
    .SetEmpty = &SetEmpty,
    .IsEmpty = &IsEmpty
};

main.c 

#include "queue.h"

#define DATALEN 100

void main(void)
{
    uint8_t getvalue;
    Queue_Pro queue;
    uint8_t  databuf[DATALEN];
    queue_Ops.Create(&queue,DATALEN);

    /* 入队列 */

    if(queue_Ops.Enqueue(&queue))
    {
        databuf[queue.tail++] = 10;
    }

     if(queue_Ops.Enqueue(&queue))
    {
        databuf[queue.tail++] = 20;
    }

     if(queue_Ops.Enqueue(&queue))
    {
        databuf[queue.tail++] = 30;
    }

    /* 出队列 */

    if(queue_Ops.Dequeue(&queue))
    {
        getvalue=databuf[queue.head++];
    }

     if(queue_Ops.Dequeue(&queue))
    {
        getvalue=databuf[queue.head++];
    }

     if(queue_Ops.Dequeue(&queue))
    {
        getvalue=databuf[queue.head++];
    }
    

}

在C语言中实现的一个简单循环队列(Circular Queue)数据结构,该结构包括头文件定义、方法实现以及主函数调用。以下是各部分的具体说明:

头文件(queue.h) 在头文件中,首先定义了两个核心结构体类型:

  1. Queue_Pro: 表示队列对象本身,其中包含了队列的核心属性:

    • 容量(capacity): 存储队列的最大元素数量。
    • 头指针(head): 指向队列头部的索引。
    • 尾指针(tail): 指向队列尾部即将插入新元素的位置。
    • 当前队列缓存长度(size): 记录当前队列中元素的数量。
  2. Queue_Ops: 作为一个函数指针集合,封装了对队列进行的各种操作,如创建队列、入队、出队、清空队列和判断队列是否为空等。

最后,在头文件中声明了一个外部引用常量queue_Ops,它将指向这些操作的具体实现函数。

方法实现 这部分实现了在头文件中声明的所有队列操作函数:

  • Create: 初始化队列,设置其容量,并将头指针、尾指针初始化为0,同时将当前队列大小设为0。

  • Enqueue: 实现入队操作,检查队列是否已满,若未满,则执行入队动作,更新尾指针和队列大小。

  • Dequeue: 实现出队操作,检查队列是否为空,若非空,则执行出队动作,更新头指针并减少队列大小。

  • SetEmpty: 清空队列,将头指针、尾指针重置为0,并将队列大小设为0。

  • IsEmpty: 判断队列是否为空,返回一个布尔值表示结果。

全局变量声明与初始化 这部分将上述定义的方法绑定到queue_Ops结构体实例上,这样可以通过该实例方便地调用对应的操作函数。

主函数main() 在主函数中:

  1. 首先定义了一个队列实例queue,并分配了一个名为databuf的数据缓冲区用于存放队列中的数据元素。

  2. 调用queue_Ops.Create(&queue, DATALEN)以创建一个容量为DATALEN的队列。

  3. 接着,连续执行三次入队操作,分别将数值10、20、30放入队列,通过databuf[queue.tail++]存储实际数据。

  4. 然后同样执行三次出队操作,每次成功出队后从databuf[queue.head++]取出数据并存放在变量getvalue中。

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫气东来d

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值