如何用更高层次编写嵌入式C代码?
扫描二维码
随时随地手机看文章
1. 简介
市面上介绍C语言以及编程方法的书数目繁多,但对如何编写优质嵌入式C程序却鲜有介绍,特别是对应用于单片机、ARM7、Cortex-M3这类微控制器上的优质C程序编写方法几乎是个空白。本文面向的,正是使用单片机、ARM7、Cortex-M3这类微控制器的底层编程人员。编写优质嵌入式C程序绝非易事,它跟设计者的思维和经验积累关系密切。嵌入式C程序员不仅需要熟知硬件的特性、硬件的缺陷等,更要深入一门语言编程,不浮于表面。为了更方便的操作硬件,还需要对编译器进行深入的了解。本文将从语言特性、编译器、防御性编程、测试和编程思想这几个方面来讨论如何编写优质嵌入式C程序。与很多杂志、书籍不同,本文提供大量真实实例、代码段和参考书目,不仅介绍应该做什么,还重点介绍如何做、以及为什么这样做。编写优质嵌入式C程序涉及面十分广,需要程序员长时间的经验积累,本文希望能缩短这一过程。2. C语言特性
语言是编程的基石,C语言诡异且有种种陷阱和缺陷,需要程序员多年历练才能达到较为完善的地步。虽然有众多书籍、杂志、专题讨论过C语言的陷阱和缺陷,但这并不影响本节再次讨论它。总是有大批的初学者,前仆后继的倒在这些陷阱和缺陷上,民用设备、工业设备甚至是航天设备都不例外。本节将结合具体例子再次审视它们,希望引起足够重视。深入理解C语言特性,是编写优质嵌入式C程序的基础。2.1处处都是陷阱
2.1.1 无心之过
1) “=”和”==”将比较运算符”==”误写成赋值运算符”=”,可能是绝大多数人都遇到过的,比如下面代码:1. if(x=5)
2. {
3. //其它代码
4. }
代码的本意是比较变量x是否等于常量5,但是误将”==”写成了”=”,if语句恒为真。如果在逻辑判断表达式中出现赋值运算符,现在的大多数编译器会给出警告信息。比如keil MDK会给出警告提示:“warning: #187-D: use of "=" where"==" may have been intended”,但并非所有程序员都会注意到这类警告,因此有经验的程序员使用下面的代码来避免此类错误:1. if(5==x)
2. {
3. //其它代码
4. }
将常量放在变量x的左边,即使程序员误将’==’写成了’=’,编译器会产生一个任谁也不能无视的语法错误信息:不可给常量赋值!2) 复合赋值运算符复合赋值运算符( =、*=等等)虽然可以使表达式更加简洁并有可能产生更高效的机器代码,但某些复合赋值运算符也会给程序带来隐含Bug,比如” =”容易误写成”= ”,代码如下:1. tmp= 1;
代码本意是想表达tmp=tmp 1,但是将复合赋值运算符” =”误写成”= ”:将正整数常量1赋值给变量tmp。编译器会欣然接受这类代码,连警告都不会产生。如果你能在调试阶段就发现这个Bug,真应该庆祝一下,否则这很可能会成为一个重大隐含Bug,且不易被察觉。复合赋值运算符”-=”也有类似问题存在。3) 其它容易误写- 使用了中文标点
- 头文件声明语句最后忘记结束分号
- 逻辑与