mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 08:46:42 +08:00
Add PID,filter,search, update some readme
This commit is contained in:
parent
dd10129245
commit
96f9b08093
91
README.en.md
91
README.en.md
@ -1,37 +1,76 @@
|
||||
# varch
|
||||
# varch
|
||||
|
||||
#### Description
|
||||
嵌入式C语言常用代码模块库,包含了嵌入式中常用的算法库、数据结构(容器)库、解析器库、独立C语言std库、工具库等等。
|
||||
具有简单、通用、高效的特点,目的为了学习以及在开发中拿来就用,提高开发效率以及代码可靠稳定性。
|
||||

|
||||
|
||||
#### Software Architecture
|
||||
Software architecture description
|
||||
## Introduction
|
||||
|
||||
#### Installation
|
||||
[中文版](README.md)
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
varch (we architecture, meaning our framework library) is a commonly used code module library for embedded C language, including algorithm libraries, data structure (container) libraries, parser libraries, independent C language std libraries, tool libraries, and more.
|
||||
It has the characteristics of **simplicity, universality, and efficiency**, with the aim of **learning** and **using it immediately** in development, improving development efficiency and code reliability and stability.
|
||||
|
||||
#### Instructions
|
||||
## Content
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
| module | version | usage | path | describe |
|
||||
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
||||
| overall | 00.01.00 | [link](README.md) | ./ | Overall
|
||||
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | Initialize export module
|
||||
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | Console command input, combined with the 'command' module, parsing commands entered in the console
|
||||
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | Indefinite parameters, obtain the number of indefinite parameters and specified parameters
|
||||
| calculate | 01.00.00 | [link](/doc/calculate.md) | ./source/01_general | Calculation module, input calculation expression to obtain calculation result
|
||||
| command | 01.00.00 | [link](/doc/command.md) | ./source/01_general | Command parsing module, input string commands (similar to shell commands), execute corresponding command functions
|
||||
| cPatten | 01.00.00 | [link](/doc/cPatten.md) | ./source/01_general | Artistic character patterns
|
||||
| cQueue | 01.00.00 | [link](/doc/cQueue.md) | ./source/01_general | Universal queue controller
|
||||
| dList | 01.00.00 | [link](/doc/dList.md) | ./source/01_general | Universal double-link list controller
|
||||
| fsm | 01.00.00 | [link](/doc/fsm.md) | ./source/01_general | Universal finite state machine module
|
||||
| kern | 01.00.00 | [link](/doc/kern.md) | ./source/01_general | The kernel module for scheduling periodic tasks is mostly used in varch testing
|
||||
| oscp | 01.00.00 | [link](/doc/oscp.md) | ./source/01_general | Analog oscilloscope module, can easily monitor the waveform of variable changes
|
||||
| sList | 01.00.00 | [link](/doc/sList.md) | ./source/01_general | Universal single-link list controller
|
||||
| tool | 01.00.00 | [link](/doc/tool.md) | ./source/01_general | General tools code
|
||||
| valloc | 01.00.00 | [link](/doc/valloc.md) | ./source/01_general | Dynamic memory usage testing tool
|
||||
| vlog | 01.00.00 | [link](/doc/vlog.md) | ./source/01_general | Log output module
|
||||
| vctype | 01.00.00 | [link](/doc/vctype.md) | ./source/02_vstd | Similar to the C standard library ctype
|
||||
| vmath | 01.00.00 | [link](/doc/vmath.md) | ./source/02_vstd | Similar to the C standard library math
|
||||
| vmem | 01.00.00 | [link](/doc/vmem.md) | ./source/02_vstd | Simple implementation of memory pool
|
||||
| vstddef | 01.00.00 | [link](/doc/vstddef.md) | ./source/02_vstd | Similar to the C standard library stddef
|
||||
| vstdint | 01.00.00 | [link](/doc/vstdint.md) | ./source/02_vstd | Similar to the C standard library stdint
|
||||
| vstdlib | 01.00.00 | [link](/doc/vstdlib.md) | ./source/02_vstd | Similar to the C standard library stdlib
|
||||
| vstring | 01.00.00 | [link](/doc/vstring.md) | ./source/02_vstd | Similar to the C standard library string
|
||||
| deque | 01.00.00 | [link](/doc/deque.md) | ./source/03_container | Universal double-end queue container
|
||||
| dict | 01.00.00 | [link](/doc/dict.md) | ./source/03_container | Universal dictionarie container, implementation based on hash table
|
||||
| heap | 01.00.00 | [link](/doc/heap.md) | ./source/03_container | Universal heap container
|
||||
| list | 01.00.00 | [link](/doc/list.md) | ./source/03_container | Universal list container, single-link and internal iteration
|
||||
| map | 01.00.00 | [link](/doc/map.md) | ./source/03_container | Universal map container, implementation based on RB-tree
|
||||
| queue | 01.00.00 | [link](/doc/queue.md) | ./source/03_container | Universal queue container
|
||||
| set | 01.00.00 | [link](/doc/set.md) | ./source/03_container | Universal set container, implementation based on RB-tree
|
||||
| stack | 01.00.00 | [link](/doc/stack.md) | ./source/03_container | Universal stack container
|
||||
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | String class
|
||||
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | Universal tree container
|
||||
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | Universal vector(array) container
|
||||
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Verification algorithm, sum check, parity check, XOR check, LRC check
|
||||
| crc | 01.00.00 | [link](/doc/crc.md) | ./source/04_algorithm | Universal and standard CRC algorithms
|
||||
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | Encryption and decryption algorithms
|
||||
| filter | 01.00.00 | [link](/doc/filter.md) | ./source/04_algorithm | Filter algorithms, median, kalman, average
|
||||
| hash | 01.00.00 | [link](/doc/hash.md) | ./source/04_algorithm | Hash algorithms, bkdr, ap, djb, js, rs, sdbm, pjw, elf, dek, bp, fnv, jdk6
|
||||
| pid | 01.00.00 | [link](/doc/pid.md) | ./source/04_algorithm | PID control algorithm calculator
|
||||
| search | 01.00.00 | [link](/doc/search.md) | ./source/04_algorithm | Universal search algorithms, linear, binary
|
||||
| sort | 01.00.00 | [link](/doc/sort.md) | ./source/04_algorithm | Universal sorting algorithms (various data structures), bubble, select, insert, hill, quick, heap
|
||||
| csv | 01.00.00 | [link](/doc/csv.md) | ./source/05_parser | CSV file parsing generator
|
||||
| ini | 01.00.00 | [link](/doc/ini.md) | ./source/05_parser | INI configuration file parsing generator
|
||||
| json | 01.00.00 | [link](/doc/json.md) | ./source/05_parser | JSON file parsing generator
|
||||
| txls | 01.00.00 | [link](/doc/txls.md) | ./source/05_parser | TXLS file parsing generator
|
||||
| xml | 01.00.00 | [link](/doc/xml.md) | ./source/05_parser | XML file parsing generator
|
||||
|
||||
#### Contribution
|
||||
## Usage
|
||||
|
||||
1. Fork the repository
|
||||
2. Create Feat_xxx branch
|
||||
3. Commit your code
|
||||
4. Create Pull Request
|
||||
The code is compiled and tested in a Linux environment. It can be compiled by configuring the files to be compiled in the `makefile` directory under the `build` directory, or by directly running the `run. sh` file to compile and run. The varch module should be kept as independent as possible, and in order to reduce dependence on other modules, most files can be directly extracted and used separately. If there are dependencies on other modules during compilation to solve dependency problems, but only data type dependencies, you can refer to defining the required types.
|
||||
|
||||
## License
|
||||
|
||||
#### Gitee Feature
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
## Contach
|
||||
|
||||
Lamdonn@163.com
|
||||
|
||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
|
||||
208
README.md
208
README.md
@ -1,163 +1,65 @@
|
||||
# varch
|
||||
|
||||

|
||||

|
||||
|
||||
## 介绍
|
||||
|
||||
varch(we-architecture,意为我们的框架库)是嵌入式C语言常用代码模块库,包含了嵌入式中常用的算法库、数据结构(容器)库、解析器库、独立C语言std库、工具库等等。
|
||||
具有**简单、通用、高效**的特点,目的为了**学习**以及在开发中**拿来就用**,提高开发效率以及代码可靠稳定性。
|
||||
[English version](README.en.md)
|
||||
|
||||
varch(we-architecture,意为我们的框架库)是嵌入式C语言常用代码模块库,包含了嵌入式中常用的算法库, 数据结构(容器)库, 解析器库, 独立C语言std库, 工具库等等。
|
||||
具有**简单, 通用, 高效**的特点,目的为了**学习**以及在开发中**拿来就用**,提高开发效率以及代码可靠稳定性。
|
||||
|
||||
## 内容
|
||||
|
||||
### 一级目录结构
|
||||
```
|
||||
> varch
|
||||
|---> built // 编译相关的文件夹
|
||||
|---> doc // varch模块介绍文档
|
||||
|---> source // varch源码目录
|
||||
|---> LICENSE // 开源许可 GPL3
|
||||
'---> README.md // 本文件
|
||||
```
|
||||
|
||||
### 二级目录source
|
||||
```
|
||||
> source
|
||||
|---> general // 存放varch一般的代码
|
||||
|---> application // 存放应用层的代码
|
||||
|---> platform // 存放平台相关的代码
|
||||
|---> template // 存放模板型代码,一般是相同模块不同实现形式的代码
|
||||
|---> lib // 通用库代码
|
||||
|---> tool // 工具库代码
|
||||
'---> devices // 模拟设备代码
|
||||
```
|
||||
|
||||
### 三级目录
|
||||
|
||||
#### general
|
||||
```
|
||||
> source/general
|
||||
|---> calculate // 计算式模块,输入计算表达式得到计算结果
|
||||
|---> command // 命令解析模块,输入字符串命令(类似shell命令),执行相应命令函数
|
||||
|---> vlog // 日志输出模块
|
||||
|---> kern // 周期任务调度内核模块,在varch测试中基本都是使用此周期任务
|
||||
|---> vserdes // 虚拟串行解串器模块
|
||||
|---> vcan // 虚拟CAN总线通信模块
|
||||
|---> vuart // 虚拟uart串口通信模块
|
||||
|---> vio // 虚拟IO口模块
|
||||
'---> std_types.h // varch标准类型头文件
|
||||
```
|
||||
|
||||
#### lib
|
||||
```
|
||||
> source/lib
|
||||
|---> container // 数据结构容器库
|
||||
|---> algorithm // 算法库
|
||||
|---> vstd // std库
|
||||
'---> parser // 解析器库
|
||||
```
|
||||
|
||||
* container
|
||||
```
|
||||
> source/lib/container
|
||||
|---> queue.c // 通用队列容器
|
||||
|---> queue.h
|
||||
|---> stack.c // 通用栈容器
|
||||
|---> stack.h
|
||||
|---> deque.c // 通用双端队列容器
|
||||
|---> deque.h
|
||||
|---> vector.c // 通用向量(数组)容器
|
||||
|---> vector.h
|
||||
|---> list.c // 通用链表容器
|
||||
|---> list.h
|
||||
|---> heap.c // 通用堆容器
|
||||
|---> heap.h
|
||||
|---> str.c // 字符串类
|
||||
|---> str.h
|
||||
|---> set.c // 通用集合容器
|
||||
|---> set.h
|
||||
|---> map.c // 通用映射容器
|
||||
|---> map.h
|
||||
|---> map_cfg.c // 映射容器的配置文件
|
||||
|---> map_cfg.h
|
||||
|---> tree.c // 通用树容器
|
||||
|---> tree.h
|
||||
'---> tree // 基于通用树实现的各种树结构
|
||||
```
|
||||
|
||||
* algorithm
|
||||
```
|
||||
> source/lib/algorithm
|
||||
|---> encrypt.c // 加解密算法,DES、3DES
|
||||
|---> encrypt.h
|
||||
|---> checkcode.c // 校验算法,求和校验、奇偶校验、异或校验、lrc校验、标准及通用crc校验
|
||||
|---> checkcode.h
|
||||
|---> hash.c // 哈希算法,bkdr、ap、djb、js、rs、sdbm、pjw、elf、dek、bp、fnv、jdk6
|
||||
|---> hash.h
|
||||
|---> sort.c // 通用排序算法(各种数据结构),冒泡排序、选择排序、插入排序、希尔排序、快速排序、堆排序
|
||||
'---> sort.h
|
||||
```
|
||||
|
||||
* parser
|
||||
```
|
||||
> source/lib/parser
|
||||
|---> ini.c // ini配置文件解析生成器
|
||||
|---> ini.h
|
||||
|---> json.c // json文件解析生成器
|
||||
|---> json.h
|
||||
|---> xml.c // xml文件解析生成器
|
||||
|---> xml.h
|
||||
|---> txls.c // 文本表格(类markdown表格)文件解析生成器
|
||||
'---> txls.h
|
||||
```
|
||||
|
||||
* vstd
|
||||
```
|
||||
> source/lib/vstd
|
||||
|---> vstddef.h // <stddef.h>
|
||||
|---> vmath.c
|
||||
|---> vmath.h // <math.h>
|
||||
|---> vstdlib.c
|
||||
|---> vstdlib.h // <stdlib.h>
|
||||
|---> vstring.c
|
||||
|---> vstring.h // <string.h>
|
||||
|---> vctype.c
|
||||
'---> vctype.h // <ctype.h>
|
||||
```
|
||||
|
||||
#### tool
|
||||
```
|
||||
> source/tool
|
||||
|---> arg.h // 不定参数,获取不定参数个数和指定参数
|
||||
|---> valloc.c
|
||||
|---> valloc.h // 动态内存使用情况测试工具
|
||||
|---> tool.c
|
||||
'---> tool.h // 通用工具
|
||||
```
|
||||
|
||||
#### platform
|
||||
```
|
||||
> source/platform
|
||||
|---> bsp_io // 模拟IO物理层
|
||||
|---> tstamp // 在linux平台获取的时间戳
|
||||
|---> platform_types.h // 平台的基本数据类型
|
||||
'---> init // 初始化导出模块
|
||||
```
|
||||
|
||||
#### application
|
||||
```
|
||||
> source/application
|
||||
|---> main.c // 主函数所在文件
|
||||
|---> console // 控制台命令输入,与'command'模块搭配,在控制台输入命令进行解析
|
||||
'---> test // 各个模块的测试代码
|
||||
```
|
||||
|
||||
#### devices
|
||||
```
|
||||
> source/devices
|
||||
|---> ecu // 仿真模拟ECU
|
||||
|---> dtool // 仿真模拟DTOOL
|
||||
'---> lidar // 仿真模拟LIDAR
|
||||
```
|
||||
| module | version | usage | path | describe |
|
||||
|:-------------|:---------|:-----------------------------|:--------------------------------------|:--------------------------------------|
|
||||
| overall | 00.01.00 | [link](README.md) | ./ | Overall
|
||||
| init | 01.00.00 | [link](/doc/init.md) | ./source/00_application | Initialize export module
|
||||
| console | 01.00.00 | [link](/doc/console.md) | ./source/00_application/console | Console command input, combined with the 'command' module, parsing commands entered in the console
|
||||
| arg | 01.00.00 | [link](/doc/arg.md) | ./source/01_general | Indefinite parameters, obtain the number of indefinite parameters and specified parameters
|
||||
| calculate | 01.00.00 | [link](/doc/calculate.md) | ./source/01_general | Calculation module, input calculation expression to obtain calculation result
|
||||
| command | 01.00.00 | [link](/doc/command.md) | ./source/01_general | Command parsing module, input string commands (similar to shell commands), execute corresponding command functions
|
||||
| cPatten | 01.00.00 | [link](/doc/cPatten.md) | ./source/01_general | Artistic character patterns
|
||||
| cQueue | 01.00.00 | [link](/doc/cQueue.md) | ./source/01_general | Universal queue controller
|
||||
| dList | 01.00.00 | [link](/doc/dList.md) | ./source/01_general | Universal double-link list controller
|
||||
| fsm | 01.00.00 | [link](/doc/fsm.md) | ./source/01_general | Universal finite state machine module
|
||||
| kern | 01.00.00 | [link](/doc/kern.md) | ./source/01_general | The kernel module for scheduling periodic tasks is mostly used in varch testing
|
||||
| oscp | 01.00.00 | [link](/doc/oscp.md) | ./source/01_general | Analog oscilloscope module, can easily monitor the waveform of variable changes
|
||||
| sList | 01.00.00 | [link](/doc/sList.md) | ./source/01_general | Universal single-link list controller
|
||||
| tool | 01.00.00 | [link](/doc/tool.md) | ./source/01_general | General tools code
|
||||
| valloc | 01.00.00 | [link](/doc/valloc.md) | ./source/01_general | Dynamic memory usage testing tool
|
||||
| vlog | 01.00.00 | [link](/doc/vlog.md) | ./source/01_general | Log output module
|
||||
| vctype | 01.00.00 | [link](/doc/vctype.md) | ./source/02_vstd | Similar to the C standard library ctype
|
||||
| vmath | 01.00.00 | [link](/doc/vmath.md) | ./source/02_vstd | Similar to the C standard library math
|
||||
| vmem | 01.00.00 | [link](/doc/vmem.md) | ./source/02_vstd | Simple implementation of memory pool
|
||||
| vstddef | 01.00.00 | [link](/doc/vstddef.md) | ./source/02_vstd | Similar to the C standard library stddef
|
||||
| vstdint | 01.00.00 | [link](/doc/vstdint.md) | ./source/02_vstd | Similar to the C standard library stdint
|
||||
| vstdlib | 01.00.00 | [link](/doc/vstdlib.md) | ./source/02_vstd | Similar to the C standard library stdlib
|
||||
| vstring | 01.00.00 | [link](/doc/vstring.md) | ./source/02_vstd | Similar to the C standard library string
|
||||
| deque | 01.00.00 | [link](/doc/deque.md) | ./source/03_container | Universal double-end queue container
|
||||
| dict | 01.00.00 | [link](/doc/dict.md) | ./source/03_container | Universal dictionarie container, implementation based on hash table
|
||||
| heap | 01.00.00 | [link](/doc/heap.md) | ./source/03_container | Universal heap container
|
||||
| list | 01.00.00 | [link](/doc/list.md) | ./source/03_container | Universal list container, single-link and internal iteration
|
||||
| map | 01.00.00 | [link](/doc/map.md) | ./source/03_container | Universal map container, implementation based on RB-tree
|
||||
| queue | 01.00.00 | [link](/doc/queue.md) | ./source/03_container | Universal queue container
|
||||
| set | 01.00.00 | [link](/doc/set.md) | ./source/03_container | Universal set container, implementation based on RB-tree
|
||||
| stack | 01.00.00 | [link](/doc/stack.md) | ./source/03_container | Universal stack container
|
||||
| str | 01.00.00 | [link](/doc/str.md) | ./source/03_container | String class
|
||||
| tree | 01.00.00 | [link](/doc/tree.md) | ./source/03_container | Universal tree container
|
||||
| vector | 01.00.00 | [link](/doc/vector.md) | ./source/03_container | Universal vector(array) container
|
||||
| check | 01.00.00 | [link](/doc/check.md) | ./source/04_algorithm | Verification algorithm, sum check, parity check, XOR check, LRC check
|
||||
| crc | 01.00.00 | [link](/doc/crc.md) | ./source/04_algorithm | Universal and standard CRC algorithms
|
||||
| encrypt | 01.00.00 | [link](/doc/encrypt.md) | ./source/04_algorithm | Encryption and decryption algorithms
|
||||
| filter | 01.00.00 | [link](/doc/filter.md) | ./source/04_algorithm | Filter algorithms, median, kalman, average
|
||||
| hash | 01.00.00 | [link](/doc/hash.md) | ./source/04_algorithm | Hash algorithms, bkdr, ap, djb, js, rs, sdbm, pjw, elf, dek, bp, fnv, jdk6
|
||||
| pid | 01.00.00 | [link](/doc/pid.md) | ./source/04_algorithm | PID control algorithm calculator
|
||||
| search | 01.00.00 | [link](/doc/search.md) | ./source/04_algorithm | Universal search algorithms, linear, binary
|
||||
| sort | 01.00.00 | [link](/doc/sort.md) | ./source/04_algorithm | Universal sorting algorithms (various data structures), bubble, select, insert, hill, quick, heap
|
||||
| csv | 01.00.00 | [link](/doc/csv.md) | ./source/05_parser | CSV file parsing generator
|
||||
| ini | 01.00.00 | [link](/doc/ini.md) | ./source/05_parser | INI configuration file parsing generator
|
||||
| json | 01.00.00 | [link](/doc/json.md) | ./source/05_parser | JSON file parsing generator
|
||||
| txls | 01.00.00 | [link](/doc/txls.md) | ./source/05_parser | TXLS file parsing generator
|
||||
| xml | 01.00.00 | [link](/doc/xml.md) | ./source/05_parser | XML file parsing generator
|
||||
|
||||
## 使用说明
|
||||
|
||||
@ -166,7 +68,7 @@ varch(we-architecture,意为我们的框架库)是嵌入式C语言常用
|
||||
## 开源协议
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
Version 2, June 1991
|
||||
|
||||
## 联系方式
|
||||
|
||||
|
||||
53
doc/arg.md
Normal file
53
doc/arg.md
Normal file
@ -0,0 +1,53 @@
|
||||
## 介绍
|
||||
|
||||
arg模块主要针对应用布丁参数的场合,可以获取不定参数的个数及指定位置的参数。
|
||||
|
||||
## 接口
|
||||
|
||||
### 函数
|
||||
|
||||
```c
|
||||
#define ARG_MAX // 支持最大的不定参数个数
|
||||
#define ARGC(...) // 当前不定参数的个数,不支持区分空参数
|
||||
#define ARGC0(...) // 当前不定参数的个数,支持区分空参数,但编译需要更多的空间,视情况选择使用
|
||||
#define ARGS(x, ...) // 获取指定位置参数
|
||||
```
|
||||
在使用上只需关注以上的宏定义即可,其他的均可以无需关注。
|
||||
|
||||
使用例子:
|
||||
```c
|
||||
static void test(void)
|
||||
{
|
||||
printf("ARG_MAX %d\r\n", ARG_MAX);
|
||||
|
||||
printf("ARGC %d\r\n", ARGC());
|
||||
printf("ARGC %d\r\n", ARGC(A));
|
||||
printf("ARGC %d\r\n", ARGC(A, B));
|
||||
printf("ARGC %d\r\n", ARGC(A, B, C));
|
||||
|
||||
printf("ARGC %d\r\n", ARGC0());
|
||||
printf("ARGC %d\r\n", ARGC0(A));
|
||||
printf("ARGC %d\r\n", ARGC0(A, B));
|
||||
printf("ARGC %d\r\n", ARGC0(A, B, C));
|
||||
|
||||
printf("ARGS %s\r\n", ARGS(0, "arg0", "arg1", "arg2"));
|
||||
printf("ARGS %s\r\n", ARGS(1, "arg0", "arg1", "arg2"));
|
||||
printf("ARGS %s\r\n", ARGS(2, "arg0", "arg1", "arg2"));
|
||||
}
|
||||
```
|
||||
结果:
|
||||
```
|
||||
ARG_MAX 124
|
||||
ARGC 1
|
||||
ARGC 1
|
||||
ARGC 2
|
||||
ARGC 3
|
||||
ARGC 0
|
||||
ARGC 1
|
||||
ARGC 2
|
||||
ARGC 3
|
||||
ARGS arg0
|
||||
ARGS arg1
|
||||
ARGS arg2
|
||||
```
|
||||
|
||||
53
doc/cPatten.md
Normal file
53
doc/cPatten.md
Normal file
@ -0,0 +1,53 @@
|
||||
## 介绍
|
||||
|
||||
cPatten为一个简单的字符艺术字模块,通过字符组成艺术字符。
|
||||
|
||||
## 接口
|
||||
|
||||
### 函数
|
||||
|
||||
```c
|
||||
int cPatten_setMask(char c); // 设置艺术字组成字符
|
||||
void cPatten_showChar(char c); // 显示艺术字符
|
||||
void cPatten_showString(char *s); // 显示艺术字符串
|
||||
```
|
||||
|
||||
使用例子:
|
||||
```c
|
||||
static void show(void)
|
||||
{
|
||||
cPatten_setMask('`');
|
||||
cPatten_showString("Varch");
|
||||
cPatten_setMask('*');
|
||||
cPatten_showString("Varch");
|
||||
cPatten_setMask('0');
|
||||
cPatten_showString("Varch");
|
||||
cPatten_setMask('#');
|
||||
cPatten_showString("Varch");
|
||||
}
|
||||
```
|
||||
结果:
|
||||
```
|
||||
` ` ``` ``` ``` ` `
|
||||
` ` ` ` ` ` ` ` ` `
|
||||
` ` ````` ``` ` `````
|
||||
` ` ` ` ` ` ` ` ` `
|
||||
` ` ` ` ` ``` ` `
|
||||
* * *** *** *** * *
|
||||
* * * * * * * * * *
|
||||
* * ***** *** * *****
|
||||
* * * * * * * * * *
|
||||
* * * * * *** * *
|
||||
0 0 000 000 000 0 0
|
||||
0 0 0 0 0 0 0 0 0 0
|
||||
0 0 00000 000 0 00000
|
||||
0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 000 0 0
|
||||
# # ### ### ### # #
|
||||
# # # # # # # # # #
|
||||
# # ##### ### # #####
|
||||
# # # # # # # # # #
|
||||
# # # # # ### # #
|
||||
|
||||
```
|
||||
|
||||
43
doc/console.md
Normal file
43
doc/console.md
Normal file
@ -0,0 +1,43 @@
|
||||
## 介绍
|
||||
|
||||
控制台模块在程序开发和运行中扮演着关键角色,主要用于管理基于字符的应用程序的输入输出。通过控制台模块,开发者能够实现与用户的有效交互,同时对命令行界面进行定制和管理。
|
||||
|
||||
## 接口
|
||||
|
||||
### 函数
|
||||
|
||||
```c
|
||||
void console_init(void);
|
||||
```
|
||||
|
||||
控制台模块初始化模块函数,可以手动调用,也可以通过init模块导出调用(默认通过导出调用),程序运行后直接使用即可。
|
||||
|
||||
使用例子:
|
||||
```
|
||||
>> cmd -h
|
||||
|
||||
Usage:
|
||||
Enter the command line to execute the corresponding command
|
||||
|
||||
OPTIONS
|
||||
[-l] : Print currently supported commands
|
||||
[-n] : Print the number of currently supported commands
|
||||
[-h] : Print help
|
||||
[-v] : Print version
|
||||
[-c] : Print the configuration information of the current command module
|
||||
`argc` : The maximum number of parameters supported for parsing in the input command
|
||||
`line` : The maximum length supported for parsing in the input command
|
||||
`count` : The maximum command count supported
|
||||
>>
|
||||
>>
|
||||
>> cmd -l
|
||||
|
||||
command list:
|
||||
@ cmd
|
||||
@ into
|
||||
>>
|
||||
>>
|
||||
|
||||
```
|
||||
|
||||
|
||||
172
doc/filter.md
Normal file
172
doc/filter.md
Normal file
@ -0,0 +1,172 @@
|
||||
## 介绍
|
||||
|
||||
过滤算法是一种在数据处理中用于筛选和提取特定数据的技术。其核心目的是从大量数据中识别并保留符合特定条件的数据,同时排除不相关的数据。
|
||||
|
||||
### 中值滤波算法(Median Filter)
|
||||
|
||||
中值滤波算法是一种非线性滤波技术,主要用于消除噪声,尤其是椒盐噪声,同时保留图像的边缘信息。下面将详细解读中值滤波算法的原理、实现和应用:
|
||||
|
||||
* 基本原理
|
||||
|
||||
概念:中值滤波算法的基本原理是将一个像素点的灰度值替换为其邻域内所有像素点灰度值的中值。这种算法能够有效去除孤立的噪声点,同时保持图像细节不被模糊。
|
||||
|
||||
邻域选择:通常使用一个二维滑动模板(如3×3或5×5),对模板内的像素值进行排序,取中间位置的值作为当前像素的新值。
|
||||
|
||||
* 实现方法
|
||||
|
||||
数据排序:通过排序算法(如冒泡排序、快速排序等)对邻域内的数据进行排序,然后选取中值。
|
||||
|
||||
边界处理:对于图像边界的像素,可以选择不处理、重复边界值、补0或缩小窗口大小等方法进行处理。
|
||||
|
||||
* 应用场景
|
||||
|
||||
图像去噪:中值滤波尤其适用于去除椒盐噪声,被广泛应用于数字图像处理领域。
|
||||
|
||||
信号处理:在一维信号处理中,中值滤波也可用于消除异常数据点,平滑信号。
|
||||
|
||||
* 优缺点
|
||||
|
||||
优点:中值滤波在去除噪声的同时能较好地保留边缘信息,对于椒盐噪声效果显著。
|
||||
|
||||
缺点:计算量较大,特别是对于大尺寸的窗口,需要更多的计算资源和时间。
|
||||
|
||||
### 卡尔曼滤波算法(Kalman Filter)
|
||||
|
||||
卡尔曼滤波算法是一种高效的自回归数据处理算法,主要用于数据融合、状态估计和预测更新。它通过结合不同传感器的数据,得到更精确的测量值和状态估计。下面将详细解读卡尔曼滤波算法的原理、实现和应用:
|
||||
|
||||
* 基本原理
|
||||
|
||||
概念:卡尔曼滤波本质上是一个数据融合算法,它将具有同样测量目的但来自不同传感器的数据融合在一起,得到一个更精确的目的测量值。其核心在于利用前一时刻的状态(和可能的测量值)来得到当前时刻下的状态的最优估计。
|
||||
|
||||
局限性:卡尔曼滤波器只能拟合线性高斯系统,但其计算量小,效率高。
|
||||
|
||||
* 实现方法
|
||||
|
||||
预测更新:根据前一时刻的状态和运动测量值,通过状态转换方程预测当前时刻的状态向量和协方差矩阵。这一步增加了不确定性,因为状态转换和运动测量都存在噪声。
|
||||
|
||||
测量更新:当获得新的测量值时,利用测量模型对预测状态进行校正,得到更准确的状态估计。这一步需要计算卡尔曼增益,并更新状态向量和协方差矩阵。
|
||||
|
||||
* 应用场景
|
||||
|
||||
卫星导航:在GPS和IMU结合的应用中,卡尔曼滤波常用于融合不同传感器的数据,提高导航精度。
|
||||
|
||||
SLAM:尽管SLAM的主流趋势是图优化,但卡尔曼滤波仍然为数据融合提供了一个很好的参考。
|
||||
|
||||
* 优缺点
|
||||
|
||||
优点:计算量小,适合实时应用;能够有效融合多传感器数据,提高状态估计的精度。
|
||||
|
||||
缺点:仅限于线性高斯系统,对于非线性或非高斯系统,需使用扩展卡尔曼滤波或无迹卡尔曼滤波等改进算法。
|
||||
|
||||
### 均值滤波算法(Average Filter)
|
||||
|
||||
均值滤波算法是一种简单的线性滤波技术,主要用于平滑数据和消除噪声。它通过计算一个像素点周围邻域内所有像素值的平均值来替代该像素点的值。下面将详细解读均值滤波算法的原理、实现和应用:
|
||||
|
||||
* 基本原理
|
||||
|
||||
概念:均值滤波算法的基本原理是将一个像素点的灰度值替换为其邻域内所有像素点灰度值的平均值。这种算法能够有效平滑图像,消除高频噪声,但可能导致图像细节的损失。
|
||||
|
||||
邻域选择:通常使用一个二维滑动模板(如3×3或5×5),对模板内的像素值进行平均计算,得到的结果作为当前像素的新值。
|
||||
|
||||
* 实现方法
|
||||
|
||||
数据平滑:通过对滑窗内的数据求取平均值来实现数据的平滑处理。例如,对于一个一维数据集,可以选择前后各n个数据点,计算这2n+1个点的平均值作为当前点的滤波值。
|
||||
|
||||
边界处理:对于图像边界的像素,可以选择不处理、重复边界值、补0或缩小窗口大小等方法进行处理。
|
||||
|
||||
* 应用场景
|
||||
|
||||
图像处理:均值滤波广泛应用于图像去噪和平滑处理,尤其是在处理随机白噪声方面效果显著。
|
||||
|
||||
信号处理:在一维信号处理中,均值滤波也可用于消除异常数据点,平滑信号。
|
||||
|
||||
* 优缺点
|
||||
|
||||
优点:算法简单,计算量小,适合实时应用;能够有效平滑数据,消除随机噪声。
|
||||
|
||||
缺点:会损失图像细节,导致边缘模糊;对于高斯噪声等非随机噪声效果有限。
|
||||
|
||||
* 改进算法
|
||||
|
||||
加权均值滤波器:通过对邻域内的像素值进行加权平均,可以根据距离中心像素的远近分配不同的权重,从而更好地保留图像细节。
|
||||
|
||||
自适应均值滤波器:根据图像局部特性自动调整滑窗大小或权重,以适应不同区域的需求。
|
||||
|
||||
## 接口
|
||||
|
||||
```c
|
||||
void filter_median(double *data, int size, int window);
|
||||
void filter_kalman(double *measurements, double *estimates, int numMeasurements, double processNoise, double measurementNoise);
|
||||
void filter_average(double *data, int size, int window);
|
||||
```
|
||||
|
||||
## 测试
|
||||
|
||||
```c
|
||||
static void test_median(void)
|
||||
{
|
||||
double data[] = {1, 2, 3, 2.5, 3.5, 2, 3, 4, 5};
|
||||
int size = sizeof(data) / sizeof(data[0]);
|
||||
int windowSize = 3;
|
||||
|
||||
filter_median(data, size, windowSize);
|
||||
|
||||
printf("Filtered data: \n");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("%f ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
2.000000 2.000000 2.500000 2.500000 2.500000 2.500000 3.000000 4.000000 4.000000
|
||||
```
|
||||
|
||||
```c
|
||||
static void test_average(void)
|
||||
{
|
||||
double data[] = {1, 2, 3, 2.5, 3.5, 2, 3, 4, 5};
|
||||
int size = sizeof(data) / sizeof(data[0]);
|
||||
int windowSize = 3;
|
||||
|
||||
filter_average(data, size, windowSize);
|
||||
|
||||
printf("Filtered data: \n");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("%f ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
1.000000 2.000000 2.500000 2.833333 2.777778 2.592593 3.197531 4.065844 3.021948
|
||||
```
|
||||
|
||||
```c
|
||||
static void test_kalman(void)
|
||||
{
|
||||
double measurements[] = {1.0, 2.0, 3.0, 2.5, 3.5, 2.0, 3.0, 4.0, 5.0};
|
||||
double estimates[1];
|
||||
int numMeasurements = sizeof(measurements) / sizeof(measurements[0]);
|
||||
double processNoise = 0.1;
|
||||
double measurementNoise = 0.2;
|
||||
|
||||
filter_kalman(measurements, estimates, numMeasurements, processNoise, measurementNoise);
|
||||
|
||||
printf("Estimated value: %f\n", estimates[0]);
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
Estimated value: 2.826087
|
||||
```
|
||||
65
doc/init.md
Normal file
65
doc/init.md
Normal file
@ -0,0 +1,65 @@
|
||||
## 介绍
|
||||
|
||||
初始化导出模块在程序开发中扮演关键角色,它们实现代码的重用和组织的模块化。通过初始化和导出模块,开发者能够将不同功能划分至独立文件中,减少代码冗余,提高维护性和可读性。以下探讨初始化导出模块的作用及其在不同编程语言中的实现方法。
|
||||
|
||||
模块的基本作用
|
||||
封装性: 模块内部的变量和函数默认是私有的,不会污染全局作用域。这避免了不同代码块之间的命名冲突。
|
||||
可重用性: 模块可以在多个地方重复使用,从而减少代码冗余。例如,在Python中,可以创建一个包含多个数学运算函数的math_tools模块,然后在不同项目中导入和使用这些函数。
|
||||
可维护性: 通过将代码逻辑分离到不同的模块中,可以提高代码的可读性和可维护性。每个模块职责明确,修改和扩展也更加方便
|
||||
|
||||
## 接口
|
||||
|
||||
### 初始化导出
|
||||
|
||||
```c
|
||||
#define init_export_hardware(func) __initialize(func, "1")
|
||||
#define init_export_driver(func) __initialize(func, "2")
|
||||
#define init_export_system(func) __initialize(func, "3")
|
||||
#define init_export_module(func) __initialize(func, "4")
|
||||
#define init_export_app(func) __initialize(func, "5")
|
||||
```
|
||||
|
||||
init模块支持5种不同级别的初始化导出,唯一区别就是初始化函数的执行先后而已。
|
||||
|
||||
使用例子:
|
||||
```c
|
||||
void test_init_hardware(void)
|
||||
{
|
||||
printf("hardware init!\r\n");
|
||||
}
|
||||
init_export_hardware(test_init_hardware);
|
||||
|
||||
void test_init_driver(void)
|
||||
{
|
||||
printf("driver init!\r\n");
|
||||
}
|
||||
init_export_driver(test_init_driver);
|
||||
|
||||
void test_init_system(void)
|
||||
{
|
||||
printf("system init!\r\n");
|
||||
}
|
||||
init_export_system(test_init_system);
|
||||
|
||||
void test_init_module(void)
|
||||
{
|
||||
printf("module init!\r\n");
|
||||
}
|
||||
init_export_module(test_init_module);
|
||||
|
||||
void test_init_app(void)
|
||||
{
|
||||
printf("app init!\r\n");
|
||||
}
|
||||
init_export_app(test_init_app);
|
||||
|
||||
void test_init_system1(void)
|
||||
{
|
||||
printf("system1 init!\r\n");
|
||||
}
|
||||
init_export_system(test_init_system1);
|
||||
```
|
||||
|
||||
一般是在函数结束下一行导出,然后在主函数特定位置调用`init_execute()`, 程序就会在执行到`init_execute()`时候,按初始化等级进行先后调用初始化函数。
|
||||
|
||||
|
||||
74
doc/pid.md
Normal file
74
doc/pid.md
Normal file
@ -0,0 +1,74 @@
|
||||
## 介绍
|
||||
|
||||
PID算法,即比例-积分-微分算法,是一种广泛应用于工业控制系统中的反馈控制算法。它通过比较期望值和实际值之间的误差,然后根据误差的比例(P)、积分(I)和微分(D)来调整控制器的输出,从而使系统的输出更加接近期望值。
|
||||
|
||||
PID算法的基本形式如下:
|
||||
|
||||
u(t) = Kp * e(t) + Ki * ∫e(t)dt + Kd * de(t)/dt
|
||||
|
||||
其中,u(t)是控制器的输出,e(t)是期望值和实际值之间的误差,Kp、Ki和Kd分别是比例、积分和微分系数,它们需要根据具体系统进行调整以达到最佳控制效果。
|
||||
|
||||
PID算法的优点在于其简单易用,适用范围广泛,且可以通过调整参数来适应不同的系统特性。但是,对于一些复杂的非线性系统,PID算法可能无法达到理想的控制效果。
|
||||
|
||||
## 接口
|
||||
|
||||
```c
|
||||
void pid_init(PIDC *pid);
|
||||
```
|
||||
在执行PID算法计算之前,需初始化pid算法控制结构体。
|
||||
|
||||
```c
|
||||
double pid_compute(PIDC *pid);
|
||||
```
|
||||
在执行PID算法计算之前,需初始化pid算法控制结构体。
|
||||
|
||||
## 测试
|
||||
|
||||
```c
|
||||
static void test_sim(void)
|
||||
{
|
||||
PIDC pid;
|
||||
|
||||
pid_init(&pid);
|
||||
|
||||
pid.kp = 2;
|
||||
pid.ki = 0.1;
|
||||
pid.kd = 0.05;
|
||||
|
||||
pid.point = 100.0;
|
||||
|
||||
/* Simulate the process, assuming that the value of each cycle process increases by 5 */
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
pid.process += 5;
|
||||
pid_compute(&pid);
|
||||
|
||||
printf("Process Value: %.2f, PID Output: %.2f\n", pid.process, pid.output);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
Process Value: 5.00, PID Output: 204.25
|
||||
Process Value: 10.00, PID Output: 198.25
|
||||
Process Value: 15.00, PID Output: 196.75
|
||||
Process Value: 20.00, PID Output: 194.75
|
||||
Process Value: 25.00, PID Output: 192.25
|
||||
Process Value: 30.00, PID Output: 189.25
|
||||
Process Value: 35.00, PID Output: 185.75
|
||||
Process Value: 40.00, PID Output: 181.75
|
||||
Process Value: 45.00, PID Output: 177.25
|
||||
Process Value: 50.00, PID Output: 172.25
|
||||
Process Value: 55.00, PID Output: 166.75
|
||||
Process Value: 60.00, PID Output: 160.75
|
||||
Process Value: 65.00, PID Output: 154.25
|
||||
Process Value: 70.00, PID Output: 147.25
|
||||
Process Value: 75.00, PID Output: 139.75
|
||||
Process Value: 80.00, PID Output: 131.75
|
||||
Process Value: 85.00, PID Output: 123.25
|
||||
Process Value: 90.00, PID Output: 114.25
|
||||
Process Value: 95.00, PID Output: 104.75
|
||||
Process Value: 100.00, PID Output: 94.75
|
||||
```
|
||||
89
doc/search.md
Normal file
89
doc/search.md
Normal file
@ -0,0 +1,89 @@
|
||||
## 介绍
|
||||
|
||||
查找算法是用于在数据结构中查找特定元素的算法。常见的查找算法包括线性查找、二分查找、哈希查找等。下面简要介绍这些查找算法的原理和实现:
|
||||
|
||||
线性查找:线性查找是一种最简单的查找算法,它从数据结构的起始位置开始,逐个比较每个元素,直到找到目标元素或遍历完所有元素。线性查找的时间复杂度为O(n),其中n为数据结构的大小。
|
||||
|
||||
二分查找:二分查找适用于有序的数据结构,它每次将数据结构分为两半,然后根据目标元素与中间元素的比较结果来确定继续查找的子区间。二分查找的时间复杂度为O(log n)。
|
||||
|
||||
哈希查找:哈希查找通过构造哈希函数将数据映射到哈希表中,然后根据哈希值直接访问目标元素。哈希查找的平均时间复杂度为O(1)。*** 在dict模块中就应用hash查找 ***
|
||||
|
||||
## 接口
|
||||
|
||||
```c
|
||||
int search_linear(void *array, int left, int right, void *target, SearchOPS *ops);
|
||||
int search_binary(void *array, int left, int right, void *target, SearchOPS *ops);
|
||||
```
|
||||
这两种查找算法使用方法一致,都是传入数据地址、数组查找区间、查找目标和依赖于数据容器的操作集,返回查找出来的数组索引(失败将会返回负数)。
|
||||
|
||||
## 测试
|
||||
|
||||
```c
|
||||
static void test_linear(void)
|
||||
{
|
||||
int array[] = {6, 3, 1, 0, -2, 9};
|
||||
SearchOPS ops;
|
||||
int target = 1;
|
||||
|
||||
ops.addr = int_array_addr;
|
||||
ops.cmp = int_cmp;
|
||||
|
||||
target = 9, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -2, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 0, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 1, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 3, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 6, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
|
||||
target = 5, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -9, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
search 9, result 5
|
||||
search -2, result 4
|
||||
search 0, result 3
|
||||
search 1, result 2
|
||||
search 3, result 1
|
||||
search 6, result 0
|
||||
search 5, result -1
|
||||
search -9, result -1
|
||||
```
|
||||
|
||||
```c
|
||||
static void test_binary(void)
|
||||
{
|
||||
int array[] = {0, 3, 6, 10, 62, 99};
|
||||
SearchOPS ops;
|
||||
int target = 10;
|
||||
|
||||
ops.addr = int_array_addr;
|
||||
ops.cmp = int_cmp;
|
||||
|
||||
target = 0, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 3, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 6, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 10, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 62, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 99, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
|
||||
target = 5, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -9, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
}
|
||||
```
|
||||
|
||||
结果
|
||||
|
||||
```
|
||||
search 0, result 0
|
||||
search 3, result 1
|
||||
search 6, result 2
|
||||
search 10, result 3
|
||||
search 62, result 4
|
||||
search 99, result 5
|
||||
search 5, result -1
|
||||
search -9, result -1
|
||||
```
|
||||
@ -1,155 +0,0 @@
|
||||
## 介绍
|
||||
|
||||
dict字典是逻辑上离散的容器,与set容器很相似,set容器是以`index - data`形式存在,而dict容器是以`key - value`形式存在,set的index是整型数,dict的key为字符串(这里和python的dict不太一样,python的key除了可以字符串还可以整型或者元组等,varch类似python的dict叫做map映射),set的data和dict的value本质是同一个东西。
|
||||
varch的dict容器,也是具备的集合的基本属性,在底层实现上采用了**红黑树**,增删操作的效率高,而且也支持随机访问。同样作为链式结构,dict集合也支持迭代器。
|
||||
|
||||
## 接口
|
||||
|
||||
### 创建和删除dict对象
|
||||
```c
|
||||
dict_t dict_create(int dsize);
|
||||
void dict_delete(dict_t dict);
|
||||
#define dict(type) // 为了更简便的使用,对dict_create套一层宏定义
|
||||
#define _dict(dict) // 对dict_delete套一层宏定义,并在dict删除后置为空
|
||||
```
|
||||
其中**dict_t**为dict的结构体,创建方法则会返回一个空的dict对象,创建失败则返回NULL,其中`dsize`传入数据的大小。删除方法则是删除传入的dict对象。创建方法和删除应该成对使用,创建出来在结束使用应该删除掉。
|
||||
```c
|
||||
void test(void)
|
||||
{
|
||||
dict_t dict = dict(int); // 定义并创建一个int型的dict
|
||||
_dict(dict); // 成对使用,用完即删除
|
||||
}
|
||||
```
|
||||
|
||||
### dict的插入和移除
|
||||
```c
|
||||
void* dict_insert(dict_t dict, const char *key, void *value);
|
||||
int dict_erase(dict_t dict, const char *key);
|
||||
```
|
||||
dict有着较好插入和移除的效率,不用数据移位只需修改链表指向。
|
||||
dict不是通过hash值来定位的,而是从底层就对key进行比较查找,所以不存在hash冲突的问题
|
||||
插入的方法是添加指定key并将数据复制到这个键(在其中,value传入NULL时则只是开辟空间,不进行赋值),在插入key的过程中会进行查重,保证key的唯一性,插入成功后返回插入后的数据的地址,插入失败则是返回NULL。而移除则是移除指定键的数据,成功返回1,失败返回0。
|
||||
|
||||
### dict数据的读写
|
||||
```c
|
||||
void* dict_value(dict_t dict, const char *key);
|
||||
void* dict_error(dict_t dict);
|
||||
#define dict_at(dict, type, key)
|
||||
```
|
||||
`dict_value`方法就是根据键来获取数据的地址,返回的则是指定的数据的地址,`dict_error()`则是失败。而`dict_at`则是在`dict_value`的基础上加多类型,`dict_value`具备读写保护机制,因为返回的是`dict_error()`而不是NULL,所以在使用`dict_at`方法`i`写错了就会修改`dict_error()`指向的内容,而不会导致奔溃。
|
||||
dict的随机访问和连续地址的数组或者非连续地址的list都不太一样,数组是可以直接定位到指定键的地址,而链表要链式一步步指向进行随机访问。dict采用了**红黑树**,二分查找就可以很快的访问到指定键。
|
||||
|
||||
```c
|
||||
void test(void)
|
||||
{
|
||||
dict_t dict = dict(int);
|
||||
int value;
|
||||
|
||||
value = 100; dict_insert(dict, "hello", &value);
|
||||
value = 1; dict_insert(dict, "ZhangSan", &value);
|
||||
value = 2; dict_insert(dict, "LiSi", &value);
|
||||
value = 3; dict_insert(dict, "WangWu", &value);
|
||||
value = 4; dict_insert(dict, "SunLiu", &value);
|
||||
value = 5; dict_insert(dict, "QianQi", &value);
|
||||
|
||||
printf("dict[hello] = %d\r\n", dict_at(dict, int, "hello"));
|
||||
printf("dict[SunLiu] = %d\r\n", dict_at(dict, int, "SunLiu"));
|
||||
|
||||
_dict(dict);
|
||||
}
|
||||
```
|
||||
结果:
|
||||
```
|
||||
dict[hello] = 100
|
||||
dict[SunLiu] = 4
|
||||
```
|
||||
|
||||
### dict的大小和和数据大小
|
||||
```c
|
||||
int dict_size(dict_t dict);
|
||||
int dict_dsize(dict_t dict);
|
||||
```
|
||||
dict的`size`很好理解,也就是像数组那样的大小,`dsize`也就是创建时候传入的数据的大小。
|
||||
```c
|
||||
void test(void)
|
||||
{
|
||||
dict_t dict = dict(int);
|
||||
int value;
|
||||
|
||||
value = 100; dict_insert(dict, "hello", &value);
|
||||
value = 1; dict_insert(dict, "ZhangSan", &value);
|
||||
value = 2; dict_insert(dict, "LiSi", &value);
|
||||
value = 3; dict_insert(dict, "WangWu", &value);
|
||||
value = 4; dict_insert(dict, "SunLiu", &value);
|
||||
value = 5; dict_insert(dict, "QianQi", &value);
|
||||
|
||||
printf("size = %d, value size = %d\r\n", dict_size(dict), dict_dsize(dict));
|
||||
|
||||
_dict(dict);
|
||||
}
|
||||
```
|
||||
结果:
|
||||
```
|
||||
size = 6, value size = 4
|
||||
```
|
||||
|
||||
### dict查找
|
||||
```c
|
||||
int dict_find(dict_t dict, const char *key);
|
||||
```
|
||||
这个方法其实套`dict_value`实现,只是find成功返回1失败返回0。
|
||||
|
||||
### dict迭代器
|
||||
|
||||
```c
|
||||
void dict_it_init(dict_t dict, int orgin);
|
||||
void* dict_it_get(dict_t dict, char **key);
|
||||
```
|
||||
|
||||
dict也支持内置的迭代器,但主要dict的迭代器用于遍历。因为向list要遍历的时候是知道键从0开始逐一递增遍历的。但是dict是离散型的key,无法通过这种逐一递增的方式进行遍历,所以这里给定了两个迭代器函数用于遍历dict。
|
||||
`dict_it_init`初始化迭代器,`orgin`指定为`SET_HEAD`或者`SET_TAIL`,就分别是正向迭代和反向迭代。
|
||||
`dict_it_get`获取迭代,更新迭代位置,`*key`为输出的key(当前所在的key,也可以传入NULL不接收),返回迭代位置的数据。
|
||||
通过`dict_size`来把控迭代次数。
|
||||
|
||||
```c
|
||||
void test(void)
|
||||
{
|
||||
dict_t dict = dict(int);
|
||||
int value;
|
||||
char *key;
|
||||
void *data;
|
||||
int i;
|
||||
|
||||
value = 100; dict_insert(dict, "hello", &value);
|
||||
value = 1; dict_insert(dict, "ZhangSan", &value);
|
||||
value = 2; dict_insert(dict, "LiSi", &value);
|
||||
value = 3; dict_insert(dict, "WangWu", &value);
|
||||
value = 4; dict_insert(dict, "SunLiu", &value);
|
||||
value = 5; dict_insert(dict, "QianQi", &value);
|
||||
|
||||
dict_it_init(dict, DICT_HEAD);
|
||||
i = dict_size(dict);
|
||||
while (i--)
|
||||
{
|
||||
data = dict_it_get(dict, &key);
|
||||
printf("dict[%s] = %d\r\n", key, *(int *)data);
|
||||
}
|
||||
|
||||
_dict(dict);
|
||||
}
|
||||
```
|
||||
|
||||
结果:
|
||||
```
|
||||
dict[LiSi] = 2
|
||||
dict[QianQi] = 5
|
||||
dict[SunLiu] = 4
|
||||
dict[WangWu] = 3
|
||||
dict[ZhangSan] = 1
|
||||
dict[hello] = 100
|
||||
```
|
||||
|
||||
## 源码解析
|
||||
|
||||
dict与set容器保持一致。
|
||||
|
||||
6
makefile
6
makefile
@ -42,6 +42,7 @@ SOURCES += $(wildcard $(PARSER_PATH)/*.c)
|
||||
# SOURCES += $(TESTSPACE)/test_init.c
|
||||
# SOURCES += $(TESTSPACE)/test_kern.c
|
||||
# SOURCES += $(TESTSPACE)/test_valloc.c
|
||||
SOURCES += $(TESTSPACE)/test_arg.c
|
||||
# SOURCES += $(TESTSPACE)/test_vstd.c
|
||||
# SOURCES += $(TESTSPACE)/test_vlog.c
|
||||
# SOURCES += $(TESTSPACE)/test_ini.c
|
||||
@ -69,8 +70,11 @@ SOURCES += $(wildcard $(PARSER_PATH)/*.c)
|
||||
# SOURCES += $(TESTSPACE)/test_crc.c
|
||||
# SOURCES += $(TESTSPACE)/test_sort.c
|
||||
# SOURCES += $(TESTSPACE)/test_hash.c
|
||||
# SOURCES += $(TESTSPACE)/test_pid.c
|
||||
# SOURCES += $(TESTSPACE)/test_search.c
|
||||
# SOURCES += $(TESTSPACE)/test_filter.c
|
||||
# SOURCES += $(TESTSPACE)/test_oscp.c
|
||||
SOURCES += $(TESTSPACE)/test_tool.c
|
||||
# SOURCES += $(TESTSPACE)/test_tool.c
|
||||
# SOURCES += $(TESTSPACE)/test_sList.c
|
||||
# SOURCES += $(TESTSPACE)/test_dList.c
|
||||
# SOURCES += $(TESTSPACE)/test_cQueue.c
|
||||
|
||||
4
run.sh
4
run.sh
@ -17,7 +17,7 @@ else
|
||||
echo "compile fail!!!"
|
||||
fi
|
||||
|
||||
# find . -name *.h -o -name *.c | xargs wc -l
|
||||
|
||||
# enter key to continue
|
||||
read -p "Press enter to continue"
|
||||
|
||||
# find . -name *.h -o -name *.c | xargs wc -l
|
||||
|
||||
@ -21,8 +21,25 @@
|
||||
#define CPATTEN_V_MINOR 0
|
||||
#define CPATTEN_V_PATCH 0
|
||||
|
||||
/**
|
||||
* \brief Set masking character.
|
||||
* \param[in] c: Mask characters, which are artistic characters composed of these characters
|
||||
* \return 1 success or 0 fail
|
||||
*/
|
||||
int cPatten_setMask(char c);
|
||||
|
||||
/**
|
||||
* \brief Show artistic character.
|
||||
* \param[in] c: char
|
||||
* \return none
|
||||
*/
|
||||
void cPatten_showChar(char c);
|
||||
|
||||
/**
|
||||
* \brief Show artistic string.
|
||||
* \param[in] s: string
|
||||
* \return none
|
||||
*/
|
||||
void cPatten_showString(char *s);
|
||||
|
||||
|
||||
|
||||
144
source/04_algorithm/filter.c
Normal file
144
source/04_algorithm/filter.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file filter.h
|
||||
* \unit filter
|
||||
* \brief This is a C language version of commonly used filter algorithms
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "filter.h"
|
||||
|
||||
static void filter_median_s(double *data, int size, const int const window, int index)
|
||||
{
|
||||
double array[window];
|
||||
double temp;
|
||||
int i, j, half; // half windows size
|
||||
int start, end;
|
||||
|
||||
half = window / 2;
|
||||
|
||||
/* Calculate the window range for the current data point */
|
||||
start = index - half;
|
||||
end = start + window;
|
||||
|
||||
/* Ensure the window does not exceed the boundaries of the data */
|
||||
if (start < 0)
|
||||
{
|
||||
start = 0;
|
||||
end = window;
|
||||
}
|
||||
else if (end > size)
|
||||
{
|
||||
end = size;
|
||||
}
|
||||
|
||||
/* Copy the data within the window to the temporary array */
|
||||
for (i = start; i < end; i++)
|
||||
{
|
||||
array[i - start] = data[i];
|
||||
}
|
||||
|
||||
/* Sort the temporary array */
|
||||
for (i = 0; i < window - 1; i++)
|
||||
{
|
||||
for (j = 0; j < window - i - 1; j++)
|
||||
{
|
||||
if (array[j] > array[j + 1])
|
||||
{
|
||||
temp = array[j];
|
||||
array[j] = array[j + 1];
|
||||
array[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the median value and assign it to the current data point */
|
||||
data[index] = array[half];
|
||||
}
|
||||
|
||||
void filter_median(double *data, int size, int window)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Check if the window size is even, and adjust it to the next odd number if necessary */
|
||||
if (window % 2 == 0) window++;
|
||||
|
||||
/* Perform filtering for each data point */
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
filter_median_s(data, size, window, i);
|
||||
}
|
||||
}
|
||||
|
||||
void filter_kalman(double *measurements, double *estimates, int numMeasurements, double processNoise, double measurementNoise)
|
||||
{
|
||||
int i;
|
||||
double estimate, priorEstimate, priorError, errorCovariance;
|
||||
double kalmanGain, temp;
|
||||
|
||||
/* Initialize the state estimate and covariance */
|
||||
estimate = 0.0;
|
||||
priorEstimate = 0.0;
|
||||
priorError = 1.0;
|
||||
errorCovariance = priorError * priorError;
|
||||
|
||||
for (i = 0; i < numMeasurements; i++)
|
||||
{
|
||||
/* Calculate the Kalman gain */
|
||||
kalmanGain = errorCovariance / (errorCovariance + measurementNoise);
|
||||
|
||||
/* Update the state estimate */
|
||||
estimate = priorEstimate + kalmanGain * (measurements[i] - priorEstimate);
|
||||
|
||||
/* Update the covariance */
|
||||
errorCovariance = (1 - kalmanGain) * errorCovariance;
|
||||
|
||||
/* Update the prior estimate and error */
|
||||
priorEstimate = estimate;
|
||||
// priorError = errorCovariance;
|
||||
}
|
||||
|
||||
/* Store the final estimate in the estimates array */
|
||||
estimates[0] = estimate;
|
||||
}
|
||||
|
||||
void filter_average(double *data, int size, int window)
|
||||
{
|
||||
int i, j, half;
|
||||
double sum = 0.0;
|
||||
int start, end;
|
||||
|
||||
/* Check if the window size is even, and adjust it to the next odd number if necessary */
|
||||
if (window % 2 == 0) window++;
|
||||
|
||||
half = window / 2;
|
||||
|
||||
/* Perform filtering for each data point */
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
/* Reset the sum of elements within the window */
|
||||
sum = 0.0;
|
||||
|
||||
/* Calculate the window range for the current data point */
|
||||
start = i - half;
|
||||
end = start + window;
|
||||
|
||||
/* Ensure the window does not exceed the boundaries of the data */
|
||||
if (start < 0) start = 0;
|
||||
if (end > size) end = size;
|
||||
|
||||
/* Calculate the sum of all data within the window */
|
||||
for (j = start; j < end; j++)
|
||||
{
|
||||
sum += data[j];
|
||||
}
|
||||
|
||||
/* Calculate the average and assign it to the current data point */
|
||||
data[i] = sum / window;
|
||||
}
|
||||
}
|
||||
|
||||
58
source/04_algorithm/filter.h
Normal file
58
source/04_algorithm/filter.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file filter.h
|
||||
* \unit filter
|
||||
* \brief This is a C language version of commonly used filter algorithms
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __filter_H
|
||||
#define __filter_H
|
||||
|
||||
#define FILTER_V_MAJOR 1
|
||||
#define FILTER_V_MINOR 0
|
||||
#define FILTER_V_PATCH 0
|
||||
|
||||
/**
|
||||
* \brief Performs median filtering on a data array.
|
||||
*
|
||||
* This function applies median filtering to a data array using a sliding window of a specified size.
|
||||
* The filtered value at each data point is calculated as the median of the values within the window.
|
||||
*
|
||||
* \param[in,out] data A pointer to the data array to be filtered. The filtered values will be stored in this array.
|
||||
* \param[in] size The size of the data array.
|
||||
* \param[in] window The size of the sliding window for median calculation. If it is an even number, it will be adjusted to the next odd number.
|
||||
*/
|
||||
void filter_median(double *data, int size, int window);
|
||||
|
||||
/**
|
||||
* \brief Performs Kalman filtering on a series of measurements.
|
||||
*
|
||||
* This function applies Kalman filtering to a series of measurements to estimate the underlying state.
|
||||
* The estimated state at each measurement is stored in the estimates array.
|
||||
*
|
||||
* \param[in] measurements A pointer to the array of measurements.
|
||||
* \param[out] estimates A pointer to the array where the estimated states will be stored.
|
||||
* \param[in] numMeasurements The number of measurements.
|
||||
* \param[in] processNoise The process noise.
|
||||
* \param[in] measurementNoise The measurement noise.
|
||||
*/
|
||||
void filter_kalman(double *measurements, double *estimates, int numMeasurements, double processNoise, double measurementNoise);
|
||||
|
||||
/**
|
||||
* \brief Performs average filtering on a data array.
|
||||
*
|
||||
* This function applies average filtering to a data array using a sliding window of a specified size.
|
||||
* The filtered value at each data point is calculated as the average of the values within the window.
|
||||
*
|
||||
* \param[in,out] data A pointer to the data array to be filtered. The filtered values will be stored in this array.
|
||||
* \param[in] size The size of the data array.
|
||||
* \param[in] window The size of the sliding window for averaging. If it is an even number, it will be adjusted to the next odd number.
|
||||
*/
|
||||
void filter_average(double *data, int size, int window);
|
||||
|
||||
#endif
|
||||
55
source/04_algorithm/pid.c
Normal file
55
source/04_algorithm/pid.c
Normal file
@ -0,0 +1,55 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file pid.c
|
||||
* \unit pid
|
||||
* \brief This is a general-purpose C language pid module
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "pid.h"
|
||||
|
||||
|
||||
void pid_init(PIDC *pid)
|
||||
{
|
||||
/* Initialize pid structure members */
|
||||
pid->point = 0.0;
|
||||
pid->process = 0.0;
|
||||
pid->kp = 0.0;
|
||||
pid->ki = 0.0;
|
||||
pid->kd = 0.0;
|
||||
pid->integral = 0.0;
|
||||
pid->error = 0.0;
|
||||
pid->output = 0.0;
|
||||
}
|
||||
|
||||
double pid_compute(PIDC *pid)
|
||||
{
|
||||
double error; /* Record current error */
|
||||
double delta; /* Record delta error */
|
||||
double derivative; /* Record derivative item */
|
||||
|
||||
/* Calculate current error */
|
||||
error = pid->point - pid->process;
|
||||
|
||||
/* Calculate the change in error */
|
||||
delta = error - pid->error;
|
||||
|
||||
/* Accumulation of integral terms */
|
||||
pid->integral += error * pid->ki;
|
||||
|
||||
/* Calculate differential terms */
|
||||
derivative = delta * pid->kd;
|
||||
|
||||
/* Calculate PID output */
|
||||
pid->output = pid->kp * error + pid->integral + derivative;
|
||||
|
||||
/* Update previous error */
|
||||
pid->error = error;
|
||||
|
||||
return pid->output; /* Return controller output */
|
||||
}
|
||||
|
||||
71
source/04_algorithm/pid.h
Normal file
71
source/04_algorithm/pid.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file pid.h
|
||||
* \unit pid
|
||||
* \brief This is a general-purpose C language pid module
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __pid_H
|
||||
#define __pid_H
|
||||
|
||||
#define PID_V_MAJOR 1
|
||||
#define PID_V_MINOR 0
|
||||
#define PID_V_PATCH 0
|
||||
|
||||
/* PID controller structure */
|
||||
typedef struct
|
||||
{
|
||||
/**< Set point or target value */
|
||||
double point;
|
||||
|
||||
/**< Current value of process variable */
|
||||
double process;
|
||||
|
||||
/**< Proportional coefficient */
|
||||
double kp;
|
||||
|
||||
/**< Integration coefficient */
|
||||
double ki;
|
||||
|
||||
/**< Differential coefficient */
|
||||
double kd;
|
||||
|
||||
/**< Integral item */
|
||||
double integral;
|
||||
|
||||
/**< Previous error */
|
||||
double error;
|
||||
|
||||
/**< Controller output */
|
||||
double output;
|
||||
} PIDC;
|
||||
|
||||
/**
|
||||
* \brief Initializes the members of a PID controller structure.
|
||||
*
|
||||
* This function initializes the members of a PIDC structure with default values.
|
||||
*
|
||||
* \param[in] pid A pointer to the PIDC structure to be initialized.
|
||||
*/
|
||||
void pid_init(PIDC *pid);
|
||||
|
||||
/**
|
||||
* \brief Computes the output of a PID controller.
|
||||
*
|
||||
* This function takes a PIDC structure pointer as input and computes the output
|
||||
* of a PID controller based on the current error, previous error, integral term,
|
||||
* and derivative term.
|
||||
*
|
||||
* \param[in] pid A pointer to the PIDC structure containing the PID controller parameters and variables.
|
||||
*
|
||||
* \return The output of the PID controller.
|
||||
*/
|
||||
double pid_compute(PIDC *pid);
|
||||
|
||||
|
||||
#endif
|
||||
83
source/04_algorithm/search.c
Normal file
83
source/04_algorithm/search.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file search.h
|
||||
* \unit search
|
||||
* \brief This is a C language version of commonly used search algorithms
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "search.h"
|
||||
|
||||
int search_linear(void *array, int left, int right, void *target, SearchOPS *ops)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Check the validity of input parameters */
|
||||
if (!array) return -1;
|
||||
if (left > right || right < 0) return -1; // If the left and right boundaries are invalid, return -1
|
||||
if (!target) return -1;
|
||||
if (!ops) return -1;
|
||||
|
||||
/* Traverse the specified range of an array */
|
||||
for (i = left; i <= right; i++)
|
||||
{
|
||||
/* Compare the current element with the target element using the provided comparison function */
|
||||
if (ops->cmp(ops->addr(array, i), target) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int search_binary_s(void *array, int left, int right, int r, void *target, SearchOPS *ops)
|
||||
{
|
||||
int c = 0;
|
||||
int mid = left + (right - left) / 2;
|
||||
|
||||
/* There is an error on the left and right boundaries, and the search has failed */
|
||||
if (left > right) return -1;
|
||||
|
||||
/* Obtain comparison results */
|
||||
c = ops->cmp(ops->addr(array, mid), target) * r;
|
||||
|
||||
/* According to the comparison results, search in segments */
|
||||
if (c == 0)
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
else if (c > 0)
|
||||
{
|
||||
/* Search for the left interval */
|
||||
return search_binary_s(array, left, mid - 1, r, target, ops);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search for the right interval */
|
||||
return search_binary_s(array, mid + 1, right, r, target, ops);
|
||||
}
|
||||
}
|
||||
|
||||
int search_binary(void *array, int left, int right, void *target, SearchOPS *ops)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
/* Check the validity of input parameters */
|
||||
if (!array) return -1;
|
||||
if (left > right || right < 0) return -1;
|
||||
if (!target) return -1;
|
||||
if (!ops) return -1;
|
||||
|
||||
/* Get the current sorting rule */
|
||||
r = -ops->cmp(ops->addr(array, left), ops->addr(array, right));
|
||||
|
||||
/* Return binary search results */
|
||||
return search_binary_s(array, left, right, r, target, ops);
|
||||
}
|
||||
|
||||
|
||||
73
source/04_algorithm/search.h
Normal file
73
source/04_algorithm/search.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file search.h
|
||||
* \unit search
|
||||
* \brief This is a C language version of commonly used search algorithms
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __search_H
|
||||
#define __search_H
|
||||
|
||||
#define SEARCH_V_MAJOR 1
|
||||
#define SEARCH_V_MINOR 0
|
||||
#define SEARCH_V_PATCH 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* \brief get the address of the space where the element is located
|
||||
* \param[in] array: data handle
|
||||
* \param[in] index: item data index
|
||||
* \return address of item data
|
||||
*/
|
||||
void* (*addr)(void *array, int index);
|
||||
|
||||
/**
|
||||
* \brief function to compare element and target
|
||||
* \param[in] element: address of array element
|
||||
* \param[in] target: address of target data
|
||||
* \return positive: element > target
|
||||
* negative: element < target
|
||||
* 0: element = target
|
||||
*/
|
||||
int (*cmp)(void *element, void *target);
|
||||
} SearchOPS;
|
||||
|
||||
/**
|
||||
* \brief Performs linear search on an array.
|
||||
*
|
||||
* This function performs a linear search on the elements of an array within a specified
|
||||
* range, using a user-defined comparison function provided through the SearchOPS structure.
|
||||
*
|
||||
* \param[in] array A pointer to the array to be searched.
|
||||
* \param[in] left The left index of the search range.
|
||||
* \param[in] right The right index of the search range.
|
||||
* \param[in] target A pointer to the target element to be searched for.
|
||||
* \param[in] ops A pointer to the SearchOPS structure containing the comparison function and address function.
|
||||
*
|
||||
* \return The index of the found element if successful, or -1 if the element is not found or an error occurs.
|
||||
*/
|
||||
int search_linear(void *array, int left, int right, void *target, SearchOPS *ops);
|
||||
|
||||
/**
|
||||
* \brief Performs binary search on a sorted array.
|
||||
*
|
||||
* This function performs a binary search on the elements of a sorted array within a specified
|
||||
* range, using a user-defined comparison function provided through the SearchOPS structure.
|
||||
*
|
||||
* \param[in] array A pointer to the sorted array to be searched.
|
||||
* \param[in] left The left index of the search range.
|
||||
* \param[in] right The right index of the search range.
|
||||
* \param[in] target A pointer to the target element to be searched for.
|
||||
* \param[in] ops A pointer to the SearchOPS structure containing the comparison function and address function.
|
||||
*
|
||||
* \return The index of the found element if successful, or -1 if the element is not found or an error occurs.
|
||||
*/
|
||||
int search_binary(void *array, int left, int right, void *target, SearchOPS *ops);
|
||||
|
||||
#endif
|
||||
25
test/test_arg.c
Normal file
25
test/test_arg.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "arg.h"
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
printf("ARG_MAX %d\r\n", ARG_MAX);
|
||||
|
||||
printf("ARGC %d\r\n", ARGC());
|
||||
printf("ARGC %d\r\n", ARGC(A));
|
||||
printf("ARGC %d\r\n", ARGC(A, B));
|
||||
printf("ARGC %d\r\n", ARGC(A, B, C));
|
||||
|
||||
printf("ARGC %d\r\n", ARGC0());
|
||||
printf("ARGC %d\r\n", ARGC0(A));
|
||||
printf("ARGC %d\r\n", ARGC0(A, B));
|
||||
printf("ARGC %d\r\n", ARGC0(A, B, C));
|
||||
|
||||
printf("ARGS %s\r\n", ARGS(0, "arg0", "arg1", "arg2"));
|
||||
printf("ARGS %s\r\n", ARGS(1, "arg0", "arg1", "arg2"));
|
||||
printf("ARGS %s\r\n", ARGS(2, "arg0", "arg1", "arg2"));
|
||||
}
|
||||
init_export_app(test);
|
||||
61
test/test_filter.c
Normal file
61
test/test_filter.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "tool.h"
|
||||
#include "filter.h"
|
||||
|
||||
static void test_median(void)
|
||||
{
|
||||
double data[] = {1, 2, 3, 2.5, 3.5, 2, 3, 4, 5};
|
||||
int size = sizeof(data) / sizeof(data[0]);
|
||||
int windowSize = 3;
|
||||
|
||||
filter_median(data, size, windowSize);
|
||||
|
||||
printf("Filtered data: \n");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("%f ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void test_average(void)
|
||||
{
|
||||
double data[] = {1, 2, 3, 2.5, 3.5, 2, 3, 4, 5};
|
||||
int size = sizeof(data) / sizeof(data[0]);
|
||||
int windowSize = 3;
|
||||
|
||||
filter_average(data, size, windowSize);
|
||||
|
||||
printf("Filtered data: \n");
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("%f ", data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void test_kalman(void)
|
||||
{
|
||||
double measurements[] = {1.0, 2.0, 3.0, 2.5, 3.5, 2.0, 3.0, 4.0, 5.0};
|
||||
double estimates[1];
|
||||
int numMeasurements = sizeof(measurements) / sizeof(measurements[0]);
|
||||
double processNoise = 0.1;
|
||||
double measurementNoise = 0.2;
|
||||
|
||||
filter_kalman(measurements, estimates, numMeasurements, processNoise, measurementNoise);
|
||||
|
||||
printf("Estimated value: %f\n", estimates[0]);
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
printf("pid test!\r\n");
|
||||
|
||||
test_median();
|
||||
// test_average();
|
||||
// test_kalman();
|
||||
}
|
||||
init_export_app(test);
|
||||
36
test/test_pid.c
Normal file
36
test/test_pid.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "tool.h"
|
||||
#include "pid.h"
|
||||
|
||||
static void test_sim(void)
|
||||
{
|
||||
PIDC pid;
|
||||
|
||||
pid_init(&pid);
|
||||
|
||||
pid.kp = 2;
|
||||
pid.ki = 0.1;
|
||||
pid.kd = 0.05;
|
||||
|
||||
pid.point = 100.0;
|
||||
|
||||
/* Simulate the process, assuming that the value of each cycle process increases by 5 */
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
pid.process += 5;
|
||||
pid_compute(&pid);
|
||||
|
||||
printf("Process Value: %.2f, PID Output: %.2f\n", pid.process, pid.output);
|
||||
}
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
printf("pid test!\r\n");
|
||||
|
||||
test_sim();
|
||||
}
|
||||
init_export_app(test);
|
||||
67
test/test_search.c
Normal file
67
test/test_search.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "tool.h"
|
||||
#include "search.h"
|
||||
|
||||
static void* int_array_addr(void *array, int index)
|
||||
{
|
||||
return (void *)(&((int *)array)[index]);
|
||||
}
|
||||
|
||||
static int int_cmp(void *element, void *target)
|
||||
{
|
||||
if (*(int *)element > *(int *)target) return 1;
|
||||
else if (*(int *)element < *(int *)target) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_linear(void)
|
||||
{
|
||||
int array[] = {6, 3, 1, 0, -2, 9};
|
||||
SearchOPS ops;
|
||||
int target = 1;
|
||||
|
||||
ops.addr = int_array_addr;
|
||||
ops.cmp = int_cmp;
|
||||
|
||||
target = 9, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -2, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 0, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 1, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 3, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 6, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
|
||||
target = 5, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -9, printf("search %d, result %d\r\n", target, search_linear(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
}
|
||||
|
||||
static void test_binary(void)
|
||||
{
|
||||
int array[] = {0, 3, 6, 10, 62, 99};
|
||||
SearchOPS ops;
|
||||
int target = 10;
|
||||
|
||||
ops.addr = int_array_addr;
|
||||
ops.cmp = int_cmp;
|
||||
|
||||
target = 0, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 3, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 6, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 10, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 62, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = 99, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
|
||||
target = 5, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
target = -9, printf("search %d, result %d\r\n", target, search_binary(array, 0, sizeof(array) / sizeof(array[0]) - 1, &target, &ops));
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
printf("search test!\r\n");
|
||||
|
||||
// test_linear();
|
||||
test_binary();
|
||||
}
|
||||
init_export_app(test);
|
||||
Loading…
x
Reference in New Issue
Block a user