C语言
欲盖弥彰1314
如有一味绝境,非历十方生死。
展开
-
关于嵌入式软件分层设计
从会写代码,到想要写好代码,这个过程是很难受的。由于做的嵌入式软件,主要是MCU方面,都是要跟硬件底层打交道的软件设计,接手的别人的软件给人影响最深刻的就是典型的面向过程式编程,高层模块大量依赖低层模块,特别是高层模块依赖底层硬件。缺点: 修改底层模块,将影响高层模块。在实际应用中,底层模块又是经常要被修改的。怎么解决?依赖反转,低层模块依赖高层。怎么实现依赖反转?面向对象编程中有一个很重要的概念 —— 面向抽象接口编程。在C++中使用虚函数实现多态、抽象接口,C语言没有虚函数,对于OOPC来说只能原创 2020-09-12 16:03:38 · 3010 阅读 · 3 评论 -
C语言——软件定时器
都说程序设计 = 算法 + 数据结构。数据结构是挨踢必修课,不过好像学了数据结构之后也没用来做过啥。不知道做啥,就写个软件定时器。软件定时器数据结构typedef struct __software_timer{ u32 timeout; //初始化时间计数器 u32 rep...原创 2020-03-01 21:28:36 · 2284 阅读 · 0 评论 -
STM32串口之环形队列接收数据
文章目录废话说在前面代码实现环形队列数据结构写一字节数据到队列判断队列是否写满读一字节的数据判断队列是否为空写多个字节到队列到STM32上测试废话说在前面码代码的应该学数据结构都学过队列。环形队列是队列的一种特殊形式,应用挺广泛的。因为有太多文章关于这方面的内容,理论知识可以看别人的,下面写得挺好的:STM32进阶之串口环形缓冲区实现代码实现环形队列数据结构typedef s...原创 2020-01-04 20:51:04 · 9564 阅读 · 25 评论 -
sprintf格式化程序异常退出问题
使用sprintf格式化程序异常static char logfileBuf[1024] = {0};sprintf(logfileBuf, "<%d ms>[%s:%d %s] %s", time, __FILE__, __LINE__, __FUNCTION__, buf);直接格式化输出到logfileBuf程序异常退出开始以为会不会是logfileBuf缓冲区太小导致的,增大后依然异常退出调试才找到解决办法 char fileBuf[512] = {0}; char原创 2022-02-11 19:46:40 · 616 阅读 · 2 评论 -
C 语言获取当前位置
当前位置接口:http://ip.ws.126.net/ipquery代码:#define GET_CITY_IP "59.111.181.52"#define GET_CITY_IP_REQUEST "GET http://ip.ws.126.net/ipquery\r\n\r\n"static int socketfd = -1;static struct sockaddr_in server_addr;int main(int argc, char **argv){原创 2021-10-29 23:48:48 · 859 阅读 · 0 评论 -
Dahlin控制算法实现
参考 :https://blog.csdn.net/yin_bu_feng/article/details/85871595大林控制算法:#ifndef _DALIN_CONTROLLER_H_#define _DALIN_CONTROLLER_H_#ifndef __API__#define __API__#endif#ifndef __STATIC_INLINE__ #define __STATIC_INLINE__ static inline#endifstruct Da原创 2021-07-30 18:43:58 · 822 阅读 · 0 评论 -
记一个枚举变量引起的#if条件编译问题
#if 条件编译还是用得少,最近编写测试代码发现一个以前不知道的问题。代码1:enum { TEST_A = 0, TEST_B = 1, TEST_C = 2,}; #define TEST TEST_Bint main(){#if (TEST == TEST_A) printf("test A\r\n");#elif (TEST == TEST_B) printf("test B\r\n");#elif (TEST == TEST_C原创 2021-04-08 17:59:36 · 588 阅读 · 0 评论 -
OOP封装-隔离变化
封装 —— 保护程序的隐私, 不该让调用者知道的事,坚决不能暴露出来。为什么要封装隔离变化程序的隐私通常是程序最容易变化的部分,比如内部数据结构、内部使用的函数和全局变量等,需要把这些代码封装起来,从而让它们变化不会影响系统其他部分降低复杂度接口最小化是软件设计基本原则之一,最小化接口最容易被理解和使用,所以封装内部细节,只保留用户需要的最小接口。如何封装隐藏数据结构图方便直接访问数据结构的成员,容易造成模块之间紧密耦合,从而给以后的修改带来困难。内部使用的数据结构,外部原创 2021-01-14 12:07:11 · 323 阅读 · 0 评论 -
由一个链表引出的关于C语言指向空类型指针的问题
int main(void){ dlist_t *list = create_dlist(); //存放整数的链表 int arr[10]; for (int j = 0; j < 10; j++) { arr[j] = j; } d_elem_t node[10]; int i = 0; for (i = 0; i < 10; i++) { init_elem(&nod原创 2020-09-23 20:15:32 · 306 阅读 · 0 评论 -
数据结构回顾 —— 从双向链表中学设计
封装的好处1、隔离变化 : 将内部数据结构、内部使用函数以及全局变量等最容易变化部分封装起来,让变化的部分不影响系统其它部分。2、降低复杂度:接口最小化软件是软件设计的基本原则之一。封装内部实现细节,只暴露最小接口,让系统简单明了。—— 《系统程序员成长计划》链表数据结构链表的封装typedef struct double_link_list{ void *data; struct double_link_list *prev; struct double_link原创 2020-09-23 20:15:19 · 193 阅读 · 0 评论 -
抽象接口 — OOPC
基于多态衍生出的两个概念:抽象接口,简称接口依赖反转抽象接口概念:只包含函数指针的类OOP中的一种概念,并不是C开发中头文件引出的API描述某一个功能或动作,不涉及任何底层实现细节函数指针表示抽象方法OOPC中多态实现的核心手段 函数指针抽象接口的好处:即使没有实现相应的类也可以基于抽象接口编写应用程序依赖注入概念:向某个对象提供它所需要的其他对象。示例:/* 定义抽象栈 */typedef struct _abstract_stack{ .原创 2020-09-12 16:02:52 · 373 阅读 · 0 评论 -
面向对象——OOPC
面向对象编程面向对象的三大特性封装所谓封装就是把一组关联的数据和函数圈起来,外部只能看见部分函数,数据则完全看不见将类型定义放到头文件,一定程序上破坏类的"封装性",换来的是内存的灵活分配这是OOPC一般的做法。出于封装的考虑,任何时候都不能直接访问对象中的数据——OOPC的必须严格的一条准则设计类时提供用户可能访问的数据的相应的访问接口使用别人的类时,除非特殊说明,都不能直接访问类中的数据#ifndef _STACK_H_#define _STACK_H_#define S原创 2020-09-12 16:01:52 · 1075 阅读 · 0 评论 -
单片机开发——应用消息队列处理事件
消息队列的5个常见应用场景https://segmentfault.com/a/1190000017130224想要在单片机开发应用消息队列处理事件主要是为了解耦,减少模块与模块之间的耦合。看过挺恶心的代码,一个事件就用一个变量做标志位,全局变量满天飞。 就想着用消息队列模仿消息驱动的机制来处理事件。有类似这样处理的:https://blog.csdn.net/u012210286/article/details/83313099然而这样的话处理队列事件的函数在每次增减消息都要去改动,所以想写个原创 2020-08-19 21:25:16 · 2325 阅读 · 3 评论 -
"anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions"
打算移植下littleVgl这个GUI的,编译出现了anonymous unions are only supported in --gnu mode, or when enabled with #pragma anon_unions的错误,错误提示大致的意思是匿名联合只在gnu mode,或者在联合体有**#pragma anon_unions**下支持搜索了一下,在keil的官网中国找到了...原创 2019-06-06 09:28:09 · 4256 阅读 · 2 评论 -
数据结构——链式队列(C语言)
队列队列和栈一样是一种线性表变异体。现实中很多情况下都要排队,先来后到,队列就是类似这种情况的一种数据结构,数据只允许从同一端插入,删除只允许从另一端删除,插入操作叫 入队 ,删除操作叫出队;插入的一端叫队尾,删除的一端叫队头。队列可以用顺序存储和链式存储实现。链式存储实现代码数据结构typedef struct _data_node{ int data; stru...原创 2020-03-12 15:09:35 · 428 阅读 · 0 评论 -
数据结构——数组实现栈(C语言)
栈——线性表变异体栈是一种插入和删除都在同一端的线性表。这个同一端叫栈顶。栈的插入和删除都在同一端,所以最后插入的数据肯定会最先会被取出,这种逻辑结构叫先进后出——LIFO(Last in first out)。插入操作叫入栈,删除操作叫出栈。实现栈可以使用数组或链表来实现使用数组实现代码判断是否为空static int is_stack_empty(stack_t *s){ ...原创 2020-03-11 14:43:01 · 1191 阅读 · 0 评论 -
数据结构——链式栈(C语言)
栈——线性表变异体栈是一种插入和删除都在同一端的线性表。这个同一端叫栈顶。栈的插入和删除都在同一端,所以最后插入的数据肯定会最先会被取出,这种逻辑结构叫先进后出——LIFO(Last in first out)。插入操作叫入栈,删除操作叫出栈。代码数据结构typedef struct _data_node{ int data; struct _data_node *...原创 2020-03-10 13:10:43 · 271 阅读 · 0 评论 -
基于事件的单片机程序设计?
基于事件的单片机程序框架?不知道这个算不算事件驱动,工作中基本是写的裸机程序,这样搞能方便程序设计,在MDK中测试OK,母鸡有没啥菜鸡如本人不自知的问题。程序从大佬程序参考修改得来。https://github.com/jiejieTop/cmd-parser代码数据结构typedef struct _event { char event_flag : 1; ...原创 2020-03-10 13:22:48 · 727 阅读 · 13 评论 -
利用__attribute__((section("name")))构建初始化函数表
在嵌入式学习工作中经常初始化一个硬件就写一个初始化函数,基本都要到主函数中调用进行初始化,main函数都要改变。当利用__attribute__((section("name")))这个属性就可以构造一个初始化函数表,这样每次初始化一个硬件啥的就不用到main函数中去调用初始化函数。式在RTT初始化函数和Linux初始化驱动模块也是类似这样做的。实现代码头文件#ifndef _HARDW...原创 2020-02-21 11:42:46 · 1265 阅读 · 0 评论 -
Linux文件操作学习之C标准库
快速索引废话说在前面查看相关API如何使用1、fopen函数2、fwrite函数3、fread函数4、fclose函数5、fflush函数6、fseek函数使用相关函数读写文件废话说在前面在Linux中,有两种方式可操作文件,一种是C标准库的文件操作API来操作,另一种则是Linux的系统调用API。C标准库的文件相关API是带f开头的,如fopen、fwrite、fread等;Linux的系...原创 2019-12-02 23:57:13 · 1039 阅读 · 0 评论 -
C语言——函数指针和函数指针数组回顾
今天写代码,写着写着就用到函数指针数组,通过按键的ID和函数指针数据执行按键要做的事情。水平不够,所以这玩意不经常用,突然用到都忘记怎么用。所以回顾了下学习使用了下函数指针、函数指针数组。函数指针1、定义函数指针void (*fun_pointer)(char);2、函数指针赋值与调用 fun_pointer = print_a; (*fun_pointer)('a');要赋...原创 2019-11-28 19:15:46 · 196 阅读 · 0 评论 -
C语言宏定义函数的使用(定义单行和多行)
要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。 在软件开发过程中,经常有一些常用或者通用的功能或者代...转载 2019-07-11 10:33:12 · 6068 阅读 · 2 评论 -
计算结构体的大小
原文地址:https://blog.csdn.net/csw_100/article/details/5495309 结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的...转载 2019-04-12 18:04:50 · 226 阅读 · 0 评论 -
C语言程序进程内存布局
.init 启动代码段 调用主函数main.text 代码段.rodata 只读数据段 常量区.data 已初始化静态数据: (1)全局变量 (2)static修饰的局部变量.bss 未初始化的静态数据变量 :(1)全局变量 (2)static局部 未初始化则其数值为零运行时栈 : 局部变量和形参 都放在栈运行时堆: 自定义生命周期 malloc...原创 2019-05-01 23:58:23 · 376 阅读 · 0 评论