C语言实现标准FIFO

Posted jdh99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实现标准FIFO相关的知识,希望对你有一定的参考价值。

C语言实现标准FIFO

 

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.


说明:

本文在C语言中实现了标准FIFO,可以存储任意类型的数据。FIFO返回给应用模块的是一个int类型的索引值,本质是一个指针。通过这层封装,可以简化提供给应用模块的接口。

注意:此FIFO为满时不能写入的类型,如果需要的是满时自动覆盖,请自行修改。

 

注意:本FIFO已有升级版本,使用TZMalloc管理内存,使用起来更安全C语言实现升级版标准FIFO

 

源码:

fifo.h:

/**
* Copyright (c), 2015-2025
* @file fifo.h
* @brief fifo头文件
* @author jdh
* @verbatim 
* Change Logs:
* Date           Author       Notes
* 2018-01-24     jdh          新建
* 2018-11-06     jdh          修改成通用格式
* @endverbatim
*/

#ifndef _FIFO_H_
#define _FIFO_H_

#include "stdlib.h"
#include "stdio.h"
#include "stdarg.h"
#include "stdbool.h"
#include "string.h"
#include "math.h"

/**
* @brief 创建fifo
* @param item_sum:fifo中元素数.注意不是字节数
* @param item_size: 元素大小.单位: 字节
* @return fifo索引
*/

int fifo_create(int item_sum, int item_size);

/**
* @brief 删除fifo
* @param fifo_index: fifo索引
*/

void fifo_delete(int fifo_index);

/**
* @brief fifo检查是否可以写入
* @param fifo_index: fifo索引
* @retval false:不可以写入.true:可以写入
*/

bool fifo_writeable(int fifo_index);

/**
* @brief fifo写入
* @param fifo_index: fifo索引
* @param frame:写入元素指针
* @return false:失败.true:成功
*/

bool fifo_write(int fifo_index, void *data);

/**
* @brief fifo批量写入
* @param fifo_index: fifo索引
* @param data: 写入元素指针
* @param @param item_num:写入的元素数目
* @return false:失败.true:成功
*/

bool fifo_write_batch(int fifo_index, void *data, int item_num);

/**
* @brief fifo检查是否可以读取
* @param fifo_index: fifo索引
* @return false:不可以读取.true:可以读取
*/

bool fifo_readable(int fifo_index);

/**
* @brief fifo读取
* @param fifo_index: fifo索引
* @param data: 读取的数据
* @return false: 失败.true: 成功
*/

bool fifo_read(int fifo_index, void *data);

/**
* @brief fifo批量读取
* @param fifo_index: fifo索引
* @param data: 读取的数据
* @param item_num:读取的元素数
* @return false: 失败.true: 成功
*/

bool fifo_read_batch(int fifo_index, void *data, int item_num);

/**
* @brief fifo可读的元素数
* @param fifo_index: fifo索引
* @return 元素数
*/

int fifo_readable_item_count(int fifo_index);

/**
* @brief fifo可写的元素数
* @param fifo_index: fifo索引
* @return 元素数
*/

int fifo_writeable_item_count(int fifo_index);

#endif


 

fifo.c:

/**
* Copyright (c), 2015-2025
* @file fifo.c
* @brief fifo主文件
* @author jdh
* @verbatim
* Change Logs:
* Date           Author       Notes
* 2018-01-24     jdh          新建
* 2018-11-06     jdh          修改成通用格式
* @endverbatim
*/


#include "fifo.h"

/**
* @brief fifo结构
*/

typedef struct

    int ptr_write;
    int ptr_read;
    bool is_full;

    // fifo中存储的元素数,不是字节大小
    int item_sum;
    // 元素大小.单位: 字节
    int item_size;
    void *fifo_ptr;
 Fifo;

/**
* @brief 创建fifo
* @param item_sum:fifo中元素数.注意不是字节数
* @param item_size: 元素大小.单位: 字节
* @return fifo索引
*/

int fifo_create(int item_sum, int item_size)

    Fifo *fifo = (Fifo *)malloc(sizeof(Fifo));
    fifo->item_sum = item_sum;
    fifo->item_size = item_size;
    fifo->ptr_write = 0;
    fifo->ptr_read = 0;
    fifo->is_full = false;
    fifo->fifo_ptr = (void *)malloc(item_sum * item_size);
    return (int)fifo;


/**
* @brief 删除fifo
* @param fifo_index: fifo索引
*/

void fifo_delete(int fifo_index)

    Fifo *fifo = (Fifo *)fifo_index;
    free(fifo->fifo_ptr);
    fifo->fifo_ptr = NULL;
    free(fifo);
    fifo = NULL;


/**
* @brief fifo检查是否可以写入
* @param fifo_index: fifo索引
* @retval false:不可以写入.true:可以写入
*/

bool fifo_writeable(int fifo_index)
	
    Fifo *fifo = (Fifo *)fifo_index;
    return !fifo->is_full;


/**
* @brief fifo写入
* @param fifo_index: fifo索引
* @param frame:写入元素指针
* @return false:失败.true:成功
*/

bool fifo_write(int fifo_index, void *data)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->is_full)
	
		return false;
	
	
    memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size);
    fifo->ptr_write++;

    if (fifo->ptr_write >= fifo->item_sum)
	
        fifo->ptr_write = 0;
	
    if (fifo->ptr_write == fifo->ptr_read)
	
        fifo->is_full = true;
	
	
	return true;


/**
* @brief fifo批量写入
* @param fifo_index: fifo索引
* @param data: 写入元素指针
* @param item_num:写入的元素数目
* @return false:失败.true:成功
*/

bool fifo_write_batch(int fifo_index, void *data, int item_num)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo_writeable_item_count((int)fifo) < item_num)
    
        return false;
    

    memcpy((char *)(fifo->fifo_ptr) + fifo->ptr_write * fifo->item_size, data, fifo->item_size * item_num);
    fifo->ptr_write += item_num;

    if (fifo->ptr_write >= fifo->item_sum)
    
        fifo->ptr_write = 0;
    
    if (fifo->ptr_write == fifo->ptr_read)
    
        fifo->is_full = true;
    

    return true;


/**
* @brief fifo检查是否可以读取
* @param fifo_index: fifo索引
* @return false:不可以读取.true:可以读取
*/

bool fifo_readable(int fifo_index)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->ptr_write == fifo->ptr_read && !fifo->is_full)
	
		return false;
	
	return true;


/**
* @brief fifo读取
* @param fifo_index: fifo索引
* @param data: 读取的数据
* @return false: 失败.true: 成功
*/

bool fifo_read(int fifo_index, void *data)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->ptr_write == fifo->ptr_read && !fifo->is_full)
	
		return false;
	
    
    memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size);
    fifo->ptr_read++;
    if (fifo->ptr_read >= fifo->item_sum)
	
        fifo->ptr_read = 0;
	
    fifo->is_full = false;
	return true;


/**
* @brief fifo批量读取
* @param fifo_index: fifo索引
* @param data: 读取的数据
* @param item_num:读取的元素数
* @return false: 失败.true: 成功
*/

bool fifo_read_batch(int fifo_index, void *data, int item_num)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo_readable_item_count((int)fifo) < item_num)
    
        return false;
    

    memcpy(data, (char *)(fifo->fifo_ptr) + fifo->ptr_read * fifo->item_size, fifo->item_size * item_num);
    fifo->ptr_read += item_num;
    if (fifo->ptr_read >= fifo->item_sum)
    
        fifo->ptr_read = 0;
    
    fifo->is_full = false;
    return true;


/**
* @brief fifo可读的元素数
* @param fifo_index: fifo索引
* @return 元素数
*/

int fifo_readable_item_count(int fifo_index)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->is_full)
    
        return fifo->item_sum;
    
    else
    
        return (fifo->item_sum + fifo->ptr_write - fifo->ptr_read) % fifo->item_sum;
    


/**
* @brief fifo可写的元素数
* @param fifo_index: fifo索引
* @return 元素数
*/

int fifo_writeable_item_count(int fifo_index)

    Fifo *fifo = (Fifo *)fifo_index;
    if (fifo->is_full)
    
        return 0;
    
    else
    
        if (fifo->ptr_write == fifo->ptr_read)
        
            return fifo->item_sum;
        
        else
        
            return (fifo->item_sum + fifo->ptr_read - fifo->ptr_write) % fifo->item_sum;
        
    

 

测试代码:

#include <stdio.h>
#include "fifo.h"

#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned long

struct _Test

    uint8_t a;
    uint16_t b;
;

int main()

    // fifo1操作
    struct _Test arr;
    int fifo1 = fifo_create(10, sizeof(struct _Test));
    for (uint8_t i = 0; i < 10; i++)
    
        arr.a = i;
        arr.b = 100 + i;
        if (fifo_writeable(fifo1))
        
            fifo_write(fifo1, (void *)&arr);
            printf("可写:%d 可读:%d\\n", fifo_writeable_item_count(fifo1), fifo_readable_item_count(fifo1));
        
    
 
    while (1)
    
        if (fifo_readable(fifo1) == false)
        
            break;
        
        fifo_read(fifo1, (void *)&arr);
        printf("read:%d %d\\n", arr.a, arr.b);
    
 
    // fifo2操作
    int fifo2 = fifo_create(100, 1);
    char str_arr[100] = 0;
    memcpy(str_arr, "jdh", 3);
    fifo_write_batch(fifo2, str_arr, 3);
 
    printf("fifo2可写:%d 可读:%d\\n", fifo_writeable_item_count(fifo2), fifo_readable_item_count(fifo2));
 
    str_arr[0] = 0;
    fifo_read_batch(fifo2, str_arr, fifo_readable_item_count(fifo2));
    printf("read:%s\\n", str_arr);
    
    getchar();
    return 0;

 

测试输出:

可写:9 可读:1
可写:8 可读:2
可写:7 可读:3
可写:6 可读:4
可写:5 可读:5
可写:4 可读:6
可写:3 可读:7
可写:2 可读:8
可写:1 可读:9
可写:0 可读:10
read:0 100
read:1 101
read:2 102
read:3 103
read:4 104
read:5 105
read:6 106
read:7 107
read:8 108
read:9 109
fifo2可写:97 可读:3
read:jdh


 

以上是关于C语言实现标准FIFO的主要内容,如果未能解决你的问题,请参考以下文章

如何 用c语言 实现输入不定数目的一行整数

页面调度先进先出算法(FIFO) 用C语言描述 欢迎高手前来挑战

c语言常用库函数都有哪些

Python3标准库:queue线程安全的FIFO实现

ZZNUOJ_用C语言编写程序实现1226:等值数目(附完整源码)

C语言试题190之实现函数在第一个参数中进行查找,并返回匹配第二个参数所包含的字符的数目