C语言
文章平均质量分 78
机载软件与适航
全网同名,公众号【机载软件与适航】主理人
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
GNU C扩展语法归纳详解
定义一个变参函数 LOG,属性 format(printf,1,2) 有3个参数,第1个参数 printf 是告诉编译器,按照 printf() 函数的标准来检查;通过 format(printf,1,2) 属性声明,告诉编译器:LOG() 函数的参数,其格式字符串的位置在所有参数列表中的索引是 1,即第一个参数;这个函数定义多了一个参数 num,格式字符串在参数列表中的位置发生了变化(在所有的参数列表中,索引由1变成了2),要检查的第一个变参的位置也发生了变化(索引从原来的2变成了3)。原创 2023-11-07 19:23:44 · 803 阅读 · 1 评论 -
嵌入式中实现应用层和硬件层分层管理
以STM32为例,打开网络上下载的例程或者是购买开发板自带的例程,都会发现应用层中会有stm32f10x.h或者stm32f10x_gpio.h,这些文件严格来时属于硬件层的,如果软件层出现这些文件会显得很乱。https://gitee.com/schuck/cola_os来源:https://blog.csdn.net/ziqi5543/article/details/101512722。本次只实现如下接口,device_open 和device_close等剩下的接口可以自行研究。原创 2023-08-27 21:25:05 · 905 阅读 · 0 评论 -
谨以此文,向大家讲述嵌入式C语言的一些高阶知识,俗称“骚操作”,助你水平再上一个台阶!
C语言,是一门非常灵活而强大的编程语言。而且很多自诩为编程高手的人,偏偏就喜欢把程序写成天书,认为让别人看不懂,却能实现正确的功能,此乃技术高超的表现。所以,如果我们拿一个没有0的字符数组(字节序列)传给strlen,那么最终的结果很可能是错误的,甚至因为数组越界访问,而导致程序的崩溃。楼主是湖北人,大学毕业6年了,回想起自己的大学,影响尤为深的莫过于郭天祥和于振南了,正是这两个人牛逼的经历和学习教程,让我大学过得稍微有点方向,不浑浑噩噩,现如今2018年了,回想起2010年时候的情景,莫大的感慨和感激。原创 2023-08-27 21:12:54 · 1226 阅读 · 1 评论 -
# bin文件转汇编或C语言,可以吗?
*大概得出的结果就是:**转(反)汇编问题不大,但想要转成C语言很难,即便能转为C语言,也都是“伪C”,是你看不懂的那种C语言。**大概得出的结果就是:**转(反)汇编问题不大,但想要转成C语言很难,即便能转为C语言,也都是“伪C”,是你看不懂的那种C语言。**大概得出的结果就是:**转(反)汇编问题不大,但想要转成C语言很难,即便能转为C语言,也都是“伪C”,是你看不懂的那种C语言。如果要将其转换为可读的C语言代码,那么您需要使用逆向工程工具,如IDA Pro,OllyDbg或Radare2。原创 2023-08-27 20:54:44 · 4042 阅读 · 0 评论 -
嵌入式 C 语言宏嵌套的展开规则
已剪辑自: https://mp.weixin.qq.com/s/xos8z1tpptLpAV6kQFXpuQ嵌入式 C 语言中,宏是在预编译时用宏体内容“文本替换”代码中的宏名的。1、一般的展开规律像函数的参数一样:先展开参数,再分析函数,即由内向外展开。2、当宏中有#运算符的时候,不展开参数。3、当宏中有##运算符的时候,先展开函数,再分析参数。4、##运算符用于将参数连接到一起,预处理过程把出现在##运算符两侧的参数合并成一个符号,注意不是字符串。原创 2023-07-03 23:01:32 · 1237 阅读 · 0 评论 -
RTOS不同任务共享全局变量问题
既然不修改 update_flag,并且 update_flag 一开始的值为 0,那么 update_flag 就是一个不会改变的值,当然就是死循环!所以,在这种情况下,就需要程序员显式的告诉编译器,update_flag 是一个会发生改变的值,所以不要尝试做这样的优化。根据之前的分析,在添加的这段代码中,while() 循环中有其他代码读取了这个变量,编译后的代码会从内存中再次读取她的值。群友在群里咨询的一个问题:Freertos 里高优先级的任务中改变了全局变量值,低优先级的任务中循环等待值的改变;原创 2023-07-03 22:54:26 · 3712 阅读 · 0 评论 -
终于把系统调用给整明白了~
*本篇文章主要阐述以下两部分:**1.什么是系统调用?2.系统调用的实现?主要以Linux 操作系统和IA-32处理器举例,高级语言以C语言为例,同时也会掺杂一些其它操作系统和处理器。原创 2023-07-03 22:49:21 · 1638 阅读 · 0 评论 -
C语言的一些“骚操作”及其深层理解
已剪辑自: https://mp.weixin.qq.com/s/lmhp4hHdxHfseRRHukTf4w此系列文章,于振南老师向大家讲述嵌入式C语言的一些高阶知识,俗称“骚操作”,助你水平再上一个台阶!C语言,是一门非常灵活而强大的编程语言。同样一个算法、一个功能,我们可以把它写得中规中矩,也可以把它写得晦涩难懂。而且很多自诩为编程高手的人,偏偏就喜欢把程序写成天书,认为让别人看不懂,却能实现正确的功能,此乃技术高超的表现。我不评价这样的作法是否可取,因为每个人都有各自的风格和个性。原创 2023-07-03 22:43:27 · 1248 阅读 · 0 评论 -
结构体对齐为什么那么重要?
只是Warning么?,却不是固定的,跟CPU或系统位数有关,有时候还会出现字、双字这些概念,举例说明下:32位计算机:1字=32位=4字节,64位计算机:1字=64位=8字节所以,对于C语言的变量的存放和访问,都会按着这单位来,例如32位系统中,char是一个字节的,就按Byte来,int是4字节的,那么按Word来。而S3中的元素e_char1是按1字节对齐的,放在最前面,而e_int是按4字节对齐的,其地址位4整数倍,所以,只能找到个+4的位置,紧接着e_char2就按1字节对齐,跟其后面就可以了。原创 2023-04-05 20:55:21 · 462 阅读 · 1 评论 -
C语言如何实现动态扩容的string?
众所周知,C++ 中的string使用比较方便。最近工作中使用C语言,但又苦于没有高效的字符串实现,字符串的拼接和裁剪都比较麻烦,而且每个字符串都需要申请内存,内存的申请和释放也很容易出bug,怎么高效的实现一个不需要处理内存问题并且可以动态扩容进行拼接和裁剪的string呢?原创 2023-04-02 00:15:00 · 461 阅读 · 0 评论 -
参数类型string和const char*哪个更合理?
再一个,string(basic_string)是个封装类,它占用的空间肯定比const char*更大,这块我后续详细介绍一下string的源码分析吧。看一些C++项目时,发现有些函数传递的参数类型是const char*,我在想,为什么一个C++项目要用char*指针?用string会不会更好?可以分析出来,当传递的是"xxxx"这种串时,string方式会自动创建出个临时对象,临时对象的构造和析构会降低性能。今天,我们就来简单分析一下,函数参数使用string还是const char*,哪个更合适?原创 2023-04-02 00:10:06 · 285 阅读 · 0 评论 -
Qt QString 、String、char* 三者之间相互转换
已剪辑自: https://www.cnblogs.com/ybqjymy/p/13690311.html。使用QString自带的静态构造函数 fromStdString(string &s)即可。char *转化为QString比较容易,可以直接使用 QString的构造函数。使用QString类自带的toStdStirng()函数即可。1.先把QString类型变为QByteArray类型。2.从QByteArray类型再转为char* 类型。直接使用string自带的函数 c_str()即可。原创 2023-04-02 00:09:44 · 362 阅读 · 0 评论 -
嵌入式 C 语言宏配置的各种技巧
在项目中,我们经常会需要针对不同的需求进行不同的配置。在windows/Linux等大平台下,可能会用到配置文件 ini、xml等。而在嵌入式平台下,可能连文件系统都没有。而且很多时候我们只需要硬编码这些配置进代码里就好,不需要在运行时更改。比如每台设备的设备信息等,在整个生命周期中是不会变的。所以并不需要用那么灵活的配置文件。下面我就带大家游览一下C语言的宏配置相关技术,其可以实现灵活的代码裁剪定制。基于自己目前的积累,可能有错误或者遗漏,敬请指出。原创 2023-04-01 22:50:44 · 509 阅读 · 0 评论 -
C语言中,实现函数宏的三种方式
函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销。\ a = b;\ b = tmp;\ a = b;\ b = tmp;\ a = b;原创 2023-03-19 22:06:59 · 2671 阅读 · 0 评论 -
如何降低代码圈复杂度
已剪辑自: https://mp.weixin.qq.com/s?[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F9plFcXa-1679233463735)(null)]原创 2023-03-19 21:45:03 · 945 阅读 · 0 评论 -
【C进阶】同事用void把我给秀翻了!
上面这些函数都是与内存操作有关的函数,可能一些小伙伴使用过也不一定知道每个参数的具体类型是什么,这些void*部分的形参所传入的实参都是不需要进行强制类型转化的,所以根本就不需要关注传入指针所指向的具体类型,然而函数所返回的void。虽然void不能直接修饰变量,但是其可以用于修饰指针的指向即无类型指针void*,无类型指针那就有意义了,无类型指针不是一定要指向无类型数据,而是可以指向任意类型的数据。然而我们平时所定义的变量都会有具体的类型,int,float,char等等,那是否有void类型的变量呢?转载 2023-03-19 21:36:11 · 875 阅读 · 0 评论 -
面向对象类之间主要的几种关系
已剪辑自: https://mp.weixin.qq.com/s/ClBuraVUIPhnWceI7m78Xg嵌入式开发虽然平时C语言用的比较多,但面向对象的思维应该是每一位嵌入式软件工程师必备的知识。之前给大家分享过用C语言实现面向对象的内容,也分享过的文章。今天就再给大家拓展一下面向对象类之间的几种关系。原创 2023-02-19 21:30:28 · 904 阅读 · 0 评论 -
动态内存管理及防御性编程
C语言的优势是可以直接访问内存地址,也就是指针操作,但其缺陷也是因为直接内存访问。如何通过防御性编程提前发现问题,尽可能减少内存异常产生的后果,就是本文的重点。原创 2023-02-19 11:29:08 · 362 阅读 · 0 评论 -
用125行C语言编写一个简单的16位虚拟机
已剪辑自: https://mp.weixin.qq.com/s/ikrpGtssoKpumHXhrQdh8Q。改博文用图文代码的方式详细描述了实现的具体过程,包含每一条指令的含义。实现的具体过程,可以参看原博文。原创 2023-01-19 20:36:56 · 526 阅读 · 0 评论 -
50条C语言奇技淫巧,精品干货!
func2();逻辑就不对了。func2();}while(0)MIN(x,y)这个有点老套了,但是很有用。用uint8等来定义变量比这样的好多了,方便平台移植,特别是不用位数的单片机,这个很重要。原创 2022-12-26 23:25:29 · 31078 阅读 · 3 评论 -
如何让一个 C 语言项目调用另一个 C++ 项目中某些类所提供的接口?
C/C++不同的语言有不同的编译规则,要想实现通用,就必须告诉编译器,按照目标语言的规则进行编译!转载于:如何让一个 C 语言项目调用另一个 C++ 项目中某些类所提供的接口?- 嵌入式艺术的回答 - 知乎。原创 2022-12-23 10:16:25 · 1490 阅读 · 0 评论 -
7个硬核嵌入式C进阶要点!
数据占用大小是指不同的数据类型在平台中所占用的字节个数,不同的平台不同类型占用的字节个数稍有不同,不过在对应的平台进行开发过程中,必须要对每个数据类型的占用大小了如指掌,否则各种数据溢出,数据越界等等接踵而来。volatile修饰表示变量是易变的,编译器中的优化器在用到这个变量时必须每次都小心地从内存中重新读取这个变量的值,而不是使用保存在寄存器里的备份,有效的防止编译器自动优化,从而与软件设计相符合。const是恒定不变的意思,与指针的结合主要的问题是其const在指针中的位置导致该变量属性不同。原创 2022-12-20 23:29:31 · 778 阅读 · 0 评论 -
C语言既然可以自动为变量分配内存,为什么还要用动态分配内存呢?
已剪辑自: https://mp.weixin.qq.com/s/NRyM5KAm_jrBImmkA2WYSA如果想要弄清楚这些问题,我们首先就要了解静态内存和动态内存有什么区别,只有了解了他们两个的区别我们才能弄懂(理解)为什么需要动态分配内存!今天的文章会用到以下知识点,大家可以作为了解内容去学习:静态内存、动态内存、堆、栈、全局变量、指针等。既然要学习内存的相关知识,那我们就先从计算机的内存开始本篇的讲解吧!在计算机内存一共可以分为五个区域,其中有个区域是用来存储代码的,我们就不再进行讨论了。原创 2022-12-19 22:47:23 · 1067 阅读 · 0 评论 -
不可忽视的 C 语言陷阱!
已剪辑自: https://mp.weixin.qq.com/s/bdGuOjz1Cg3YXHwlVh5ZlA语言是编程的基石,C语言诡异且有种种陷阱和缺陷,需要程序员多年历练才能达到较为完善的地步。虽然有众多书籍、杂志、专题讨论过C语言的陷阱和缺陷,但这并不影响本文再次讨论它。总是有大批的初学者,前仆后继的倒在这些陷阱和缺陷上,民用设备、工业设备甚至是航天设备都不例外。本文将结合具体例子再次审视它们,希望引起足够重视。深入理解C语言特性,是编写优质嵌入式C程序的基础。原创 2022-12-18 20:05:04 · 1397 阅读 · 1 评论 -
GCC编译程序如何减少堆栈空间的大小?
3.默认栈空间大小可设置,总的来说这个问题更多在于避免栈溢出,因为大多数程序可能因为输入有不确定的运行行为,因此大多数时候栈空间只能靠估计,通过避免使用过大的局部变量,避免递归深度过深可以减少栈空间的大小。2.MCU裸片程序,很多环境是不方便,不支持,不鼓励使用malloc函数的,裸环境相当大一部分是不带内存管理的,你可以用全局变量,也可以自己实现内存池,这样最终堆大小可以大致可控。如果你在PC上跑模拟,程序运行过程是静态稳定没有不确定的行为,那么只要程序跑完不崩,那你可以尝试进一步减小栈空间。原创 2022-12-17 12:56:25 · 1062 阅读 · 0 评论 -
为什么char a[]的a不能用a=“hello”来赋值?
char* b里面的b是一个指向char的指针,而b可以用b=“hello”来复制。同样,a代表char数组的第一个元素的指针,类型应该也是char*,为什么b可以直接用赋值符号而a不可以呢?原创 2022-12-11 20:36:21 · 2919 阅读 · 0 评论 -
使用Dev C++进行Windows socket网络编程,需链接lws2_32库
Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。在我们使用Dev C++进行C语言编程时,如果我们引入的库是C语言标准库,那我们是不要在编译器选项中进行额外的设置的,但是如果我们使用的是一些不是C语言标准库,那我们可能就需要在编译器选择中进行设置。使用Dev C++进行Windows socket网络编程时,我们需要额外导入。原创 2022-12-11 19:41:31 · 4161 阅读 · 2 评论 -
嵌入式 C 语言进阶小技巧,弱符号和弱引用
当用户需要使用扩展功能时,就对其进行定义,链接到程序当中。如果用户不进行定义,则链接也不会报错,这使得库的功能可以很方便地进行裁剪和组合。注意:C标准里根本没有提到强、弱符号。这只是GCC这个实现定义的特性,在MS C编译器里是不存在这个概念的。版权声明:本文来源网络,版权归原作者所有。版权问题,请联系删除。原创 2022-12-10 22:39:24 · 246 阅读 · 0 评论 -
详解C语言二级指针三种内存模型
这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二级指针,二级指针就是指向指针的指针,其实就是开辟了100个指针空间,存放了100个地址。这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char * []),数组的每个元素都是一个地址。二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别。在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为。如果要打印这个数组,那么可以使用以下函数。原创 2022-12-09 00:33:39 · 355 阅读 · 0 评论 -
C语言文件操作、C++文件操作、QT文件操作汇总及对比分析
前面对C语言文件操作、C++文件操作、QT文件操作进行了比较详细的说明,文章链接如下;C语言文件操作C++文件操作QT文件操作通过大致的了解,我们知道C语言文件操作、C++文件操作、QT文件操作之间其实是有很多相似的地方,实际在开发过程中,我们甚至可以混合使用这几种文件操作方式,那这几种文件操作之间的差异在哪里呢?第一个很明显的差异是易用性方面的差异,C++文件操作、QT文件操作因为使用了面向对象,具有更好的封装性,使用起来可能会更简介易懂。第二个可能的差异是性能方面的差异,具体可以参考下面两篇文章;开个话原创 2022-12-05 19:51:46 · 1015 阅读 · 0 评论 -
C++文件操作
内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索,引入了“文件”的概念。一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。成千上万个文件如果不加分类放在一起,用户使用起来显然非常不便,因此又引入了树形目录(目录也叫文件夹)的机制,可以把文件放在不同的文件夹中,文件夹中还可以嵌套文件夹,这就便于用户对文件进行管理和使用,正如 Windows 的资源管理器呈现的那样。一般来说,文件原创 2022-12-05 19:34:53 · 3843 阅读 · 0 评论 -
C语言文件操作
我们对文件的概念已经非常熟悉了,比如常见的 Word 文档、txt 文件、源文件等。文件是数据源的一种,最主要的作用是保存数据。在操作系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件。对这些文件的操作,等同于对磁盘上普通文件的操作。例如:操作文件的正确流程为:打开文件 --> 读写文件 --> 关闭文件。文件在进行读写操作之前要先打开,使用完毕要关闭。所谓打开文件,就是获取文件的有关信息,例如文件名、文件状态、当前读写位置等,这些信息会被保存到一个 FILE 类型的结构体变量中。原创 2022-12-05 19:34:06 · 1586 阅读 · 0 评论 -
QT文件操作
已剪辑自: http://c.biancheng.net/view/9430.html很多应用程序都需要具备操作文件的能力,包括对文件内容进行读/写、创建和删除文件等,甚至某些应用程序的诞生纯粹是为了操作文件,比如 WPS Office、PDFedit 等。为此,Qt 框架提供了 QFile 类专门用来操作文件。QFile 类支持对文件进行读取、写入、删除、重命名、拷贝等操作,它既可以操作文件文件,也可以操作二进制文件。使用 QFile 类操作文件之前,程序中需引入头文件。创建 QFile 类的对象,常用的原创 2022-12-05 19:32:35 · 2498 阅读 · 0 评论 -
编写可移植C/C++程序的要点
然而,对于一些比较特殊的应用,如图形组件本身,就拿GTK+来说吧,基于X Window的功能和基于Win32的功能,两者差巨大,除了窗口、事件等基本概念外,几乎没有什么相同的,如果不事先了解各个平台的特性,在设计时就精心考虑的话,抽象出来的抽口在另外一个平台几乎无法实现。这些貌合神离的东东,端的是神出鬼没,一不小心着了它的道。**这一点是建立在分层设计之上的,大多数底层函数,像线程、同步机制和IPC机制等等,不同平台提供的函数,几乎是一一对应的,封装这些函数很简单,实现Adapter的工作几乎只是体力活。原创 2022-12-02 23:03:38 · 325 阅读 · 0 评论 -
有关C语言,定时器,周期任务的一些文章汇总
测试C语言中打印一句 hello world需要耗费多少时间【C/C++开源库】适合嵌入式的定时器调度器C语言实现的多线程定时器C语言操作时间函数,实现定时执行某个任务小程序C语言实现任务调度与定时器Linux C语言定时任务的实现原创 2022-12-01 09:53:10 · 765 阅读 · 0 评论 -
C 语言函数返回值,竟也有潜规则~
如果定义的函数是个布尔函数,也即返回值显式的使用类似于 bool 关键字定义,或者函数名类似于 is_true(),那么显然此时应该遵守C语言语法,使用“真”值表示成功,“假”值表示失败。实数要么是 0,要么非 0,因此可以将 0 看作一个比较特殊的“唯一”数值,使用 0 这个“唯一”的返回值,表示唯一的“成功”,多种非零的返回值,表示多种原因的失败,无疑更好一些。当然,myopen() 函数失败的原因可能很多,但不是本文关注的重点,本文更关心的是,该以何值表示“成功”,何值表示“失败”。原创 2022-11-28 12:04:38 · 271 阅读 · 0 评论 -
嵌入式开发中的防御性C语言编程
嵌入式产品的可靠性自然与硬件密不可分,但在硬件确定、并且没有第三方测试的前提下,使用防御性编程思想写出的代码,往往具有更高的稳定性。防御性编程首先需要认清C语言的种种缺陷和陷阱,C语言对于运行时的检查十分弱小,需要程序员谨慎的考虑代码,在必要的时候增加判断;防御性编程的另一个核心思想是假设代码运行在并不可靠的硬件上,外接干扰有可能会打乱程序执行顺序、更改RAM存储数据等等。原创 2022-11-21 21:33:14 · 731 阅读 · 0 评论 -
详解C语言二级指针三种内存模型
这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二级指针,二级指针就是指向指针的指针,其实就是开辟了100个指针空间,存放了100个地址。这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char * []),数组的每个元素都是一个地址。二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别。在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为。如果要打印这个数组,那么可以使用以下函数。原创 2022-11-07 23:02:55 · 272 阅读 · 0 评论 -
为什么C语言执行效率高,运行快?
已剪辑自: https://mp.weixin.qq.com/s/JUucTzACS-IFO3iTO77DhQ。原创 2022-11-07 22:49:01 · 502 阅读 · 0 评论 -
现在快2022年了,c++为什么还要实现(.cpp)和声明(.h)分开?
你可以不理解链接过程,但是有一个相关知识点有必要搞清楚——声明与定义。// 外部变量声明int g = 0;// 全局变量定义,由于有初始化,定义较强int g2;// 全局变量定义,没有初始化// 函数声明{return 0;} // 这是函数定义static int s_func(int a) { ……} // 这叫静态函数定义(被限定于模块内,有点模块私有那意思)声明和定义最大的区别是:声明可以重复多次,而定义只能有一个。这对我们设计.h文件提出了限制——头文件里最好只有声明,没有定义。原创 2022-10-06 16:09:20 · 5343 阅读 · 0 评论
分享