找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 139|回复: 2

聊天中无聊说起先进先出队列,手搓了1个

[复制链接]
发表于 2024-6-26 20:17:40 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
''先进先出队列(用数组做缓存区)
Type FIFO_LONG
    Buff() As Long
    xSize  As Long
    Count  As Long
    Head   As Long
End Type

Dim Fifo As FIFO_LONG

Sub FIFO_INIT(ByVal nSize As Long)
    If nSize <= 8 Then nSize = 8
    ReDim Fifo.Buff(0 To nSize - 1)
    Fifo.xSize = nSize
    Fifo.Head  = 0
    Fifo.Count = 0
End Sub

Function FIFO_PUSH(ByRef x As Long) As BOOLEAN '压入数据(尾部)
    If Fifo.Count = Fifo.xSize Then Exit Function
    Dim i As Long : i = Fifo.Head + Fifo.Count
    If i >= Fifo.xSize Then i = i - Fifo.xSize
    Fifo.Count = Fifo.Count + 1
    Fifo.Buff(i) = x : FIFO_PUSH = True
End Function

Function FIFO_SHIFT(ByRef x As Long) As BOOLEAN '吐出数据(头部)
    If Fifo.Count = 0 Then Exit Function
    Dim i As Long : i = Fifo.Head
    Fifo.Head = Fifo.Head + 1
    If Fifo.Head = Fifo.xSize Then Fifo.Head = 0
    Fifo.Count = Fifo.Count - 1
    x = Fifo.Buff(i) : FIFO_SHIFT = True
End Function
回复

使用道具 举报

发表于 2024-7-3 09:30:47 | 显示全部楼层
你能不能做一个能一下子吐出很多数据、一下子压入很多数据的 FIFO?一个数据一个数据地压入、吐出,对 IO 效率很不友好。尤其是像单片机实现 USB CDC 转串口 TTL 这块就需要 FIFO 能做到数据的批量读入写出(因为可以用到 DMA)。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2024-7-3 19:57:40 | 显示全部楼层
本帖最后由 tlwh163 于 2024-7-3 19:59 编辑

有点草率 只能说对简单数据类型 勉强可以用 请指正!

Type FIFO_LONG
    As Long Buff()     '队列空间
    As Long xSize      '缓存容量
    As Long iHead      '数据首的下标
    As Long Count      '有效数据长度
End Type

Dim Fifo As FIFO_LONG

Sub FIFO_INIT(ByVal nSize As Long)
    If nSize < 8 Then nSize = 8  '最小容量8
    ReDim Fifo.Buff(0 To nSize + nSize - 1) '多1倍空间便于操作
    Fifo.xSize = nSize : Fifo.iHead = 0 : Fifo.Count = 0
End Sub

'尾部压入数据(源数据地址,申请数量)  返回:实际装入数量
Function FIFO_PUSH(ByVal xPtr As Long, ByVal xCount As Long) As Long
    If xPtr = 0 Or xCount <= 0 Or Fifo.Count = Fifo.xSize Then
        FIFO_PUSH = 0 : Exit Function
    End If
    If (Fifo.Count + xCount) > Fifo.xSize Then  '装不下了
        xCount = (Fifo.xSize - Fifo.Count)      '多的数据丢弃
    End If
    Dim k As Long : k = (Fifo.iHead + Fifo.Count)
    If k >= Fifo.xSize Then k = k - Fifo.xSize  '队列的插入点下标   
    memcpy Varptr(Fifo.Buff(k)), xPtr, xCount * LenB(Fifo.Buff(0))
    Fifo.Count = Fifo.Count + xCount    '修正队列计数器
    FIFO_PUSH = xCount                  '返回实际接收多少个数据
    k = k + xCount - Fifo.xSize
    If k > 0 Then   '队列空间外的数据(如果有),移动到队列下标0
        k = k * LenB(Fifo.Buff(0))
        memcpy Varptr(Fifo.Buff(0)), Varptr(Fifo.Buff(Fifo.xSize)), k
    End If
End Function

''头部吐出数据(目标地址,请求数量)  返回:实际吐出数量
Function FIFO_SHIFT(ByVal xPtr As Long, ByVal xCount As Long) As Long
    If xPtr = 0 Or xCount <= 0 Or Fifo.Count = 0 Then
        FIFO_SHIFT = 0 : Exit Function
    End If
    If Fifo.Count < xCount Then xCount = Fifo.Count  '能吐多少吐多少
    Dim k As Long : k = Fifo.iHead + xCount
    If k >= Fifo.xSize Then k = k - Fifo.xSize  '新的队列首下标
    If k > 0 Then   '需要将队列头部的数据,搬一些到队列空间的尾部
        memcpy Varptr(Fifo.Buff(Fifo.xSize)), Varptr(Fifo.Buff(0)), k * LenB(Fifo.Buff(0))
    End If
    memcpy xPtr, Varptr(Fifo.Buff(Fifo.iHead)), xCount * LenB(Fifo.Buff(0))
    Fifo.Count = Fifo.Count - xCount '修正队列计数器
    Fifo.iHead = k                   '修正队列首下标
    FIFO_SHIFT = xCount              '返回实际吐出多少个数据
End Function
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-7-13 21:29 , Processed in 0.031780 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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