FunnC编程,1μFun

文件 2
C编程规范 版本:V0.1编写:侯名 日期:2015年1月10日QQ:401330597Email:omonkerman@ 审校:μFun项目组QQ群:4521393Github:待定 版本变更履历 版本 变更内容 作者 时间
2 目录 版本变更履历目录第0章背景第1章代码风格 1.0TAB宽度1.1行长度1.2函数定义/声明/调用1.3条件语句1.4循环和开关选择语句1.5空格/空行1.6预处理左对齐1.4typedef别名 第2章注释规则 2.0文件注释2.1函数注释2.3变量注释2.4实现注释2.5TODO注释2.6块注释2.7弃用说明注释 第3章函数规则第4章变量规则第5章参考资料: 1)Linux内核代码风格(中文版)2)Linuxkernelcodingstyle(English)3)GoogleC++风格指南-中文版4)GoogleC++StyleGuide(English)5)MISRA-C-2004_工业标准的C编程规范_中文版6)MISRA-2004IARWorkBench版本(英文) 推荐书目: 234553 5679111313 14 15151515151515 15151617 171717171717 18 第0章背景 μFun公益开发板项目终于要进入软件开发过程啦.任何软件项目在随着时间的推移,代码量和功能增加的同时,摆在面前的问题都是如何以系统性、规范化、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结4合起来.这是自上世纪60年代”软件危机”到目前的”软件工程”一直面临以及亟待解决的问题.其实本质就是如何写出正确、可理解、可验证,可维护的软件。
C语言是绝大部分嵌入式项目的主要编程语言.每个C程序员都知道用C语言编程很自由,但这种自由不可避免的导致它走向复杂,而且不同的程序员水平不
一,想法不同,风格迥异,使各种代码参差不齐,难以阅读和维护,容易产生bug.而我们制定这些规则在保证代码易于管理,使代码易于管理的方法之一是加强代码一致性.让任何程序员都可以快速读懂你的代码这点非常重要.保持统一编程风格并遵守约定意味着可以很容易根据“模式匹配”规则来推断各种标识符的含义.创建通用,必需的习惯用语和模式可以使代码更容易理解.在一些情况下可能有充分的理由改变某些编程风格,但我们还是应该遵循一致性原则,尽量不要这么做.某些情况下,我们会限制甚至禁止使用某些C语言特性.这么做是为了保持代码清爽,避免这些特性可能导致的各种问题.手册中列举了这类特性,并解释为什么这些特性被限制使用.注意:本手册并不是C语言教程,我们假定读者已经对C非常熟悉.文中图片中的代码均采自LinuxKernel.不指明具体出处.由于规则很多,所以可能无法 做到完全遵守,也就没有全部列出. 第1章代码风格 这是一个简短的文档,描述了μFun软件项目的首选代码风格。
代码风格是 因人而异的,而且我们并不愿意把我们的观点强加给任何人,不过本文档所讲述
5 的是μFun项目代码所必须遵守的风格,希望绝大多数其他代码也能遵守这个风 格。
 所以,请在写代码时尽量遵守本文所述的风格。
 1.0TAB宽度 TAB制表符要8个空格理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处,让代码结构层次分明。
尤其是当你盯着你的屏幕连续看了几个小时之后,你会发现大一点的缩进会使你更容易分辨缩进。
如果你需要3级以上的缩进,不管用何种方式你的代码已经有问题了,应该修正你的程序。
另外需要指明的是,不要设置编辑器将TAB制表符转换为空格. 1.1行长度  Tip:每一行代码字符数不超过80.  我们也认识到这条规则是有争议的,但很多已有代码都已经遵照这一规则,我们 感觉一致性更重要. 优点:提倡该原则的人主张强迫他们调整编辑器窗口大小很野蛮.很多人同时并排开几个代码窗口,根本没有多余空间拉伸窗口.大家都把窗口最大尺寸加以限定,并且80列宽是传统标准.为什么要改变呢?
 缺点:反对该原则的人则认为更宽的代码行更易阅读.80列的限制是上个世纪60年代的大型机的古板缺陷;现代设备具有更宽的显示屏,很轻松的可6以显示更多代码. 结论:80个字符是最大值.特例: •如果一行注释包含了超过80字符的命令或URL,出于复制粘贴的方便允许该行超过80字符. •包含长路径的#include语句可以超出80列.但应该尽量避免.•头文件保护可以无视该原则. 1.2函数定义/声明/调用 Tip:返回类型和函数名在同一行,参数也尽量放在同一行. 注意以下几点:•返回值总是和函数名在同一行;•左圆括号总是和函数名在同一行;•函数名和左圆括号间没有空格;•圆括号与参数间没有空格;•函数声明和实现处的所有形参名称必须保持一致;•所有形参应尽可能对齐; 函数调用遵循如下形式: 7如果同一行放不下,可断为多行,后面每一行都和第一个实参对齐,左圆括号后和右圆括号前不要留空格:如果函数参数很多,出于可读性的考虑可以在每行只放一个参数:  1.3条件语句 C语言风格中另外一个常见问题是大括号的放置。
和缩进大小不同,选择或弃用某种放置策略并没有多少技术上的原因,不过首选的方式,就像Kernighan和Ritchie(K&R风格)展示给我们的,是把起始大括号放在行尾,而把结束大括号放在行首,所以: 8if/else最好也遵守同样的规则,这样和Linux内核风格是兼容的,不遵守则是与Linux风格一致.各自取舍.  也请注意这种大括号的放置方式也能使空(或者差不多空的)行的数量最小化, 同时不失可读性。
因此,由于你的屏幕上的新行是不可再生资源(想想25行的终端屏幕),你将会有更多的空行来放置注释。
 当只有一个单独的语句的时候,不用加不必要的大括号。
但是我们建议你在外围加上{}约束,这样是防止后期维护人员维护升级时疏忽而忘记敲入{},导致程序Debug困难. 9如果if条件表达式超过了80个字符,应该使用以下的方式,逻辑(&&或者||)运算符总位于行尾: 注意,上例代码换行时,所有逻辑运算符均位于行尾/行首,也可以适当插入若干圆括号,合理使用的话对增强代码可读性很有帮助。
 1.4循环和开关选择语句 do…while循环注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是do语句中的“while”或者if语句中的“else”,像这样: switch语句中的case块可以使用大括号也可以不用,取决于你的个人喜 好.如果用的话,要按照下图所述的样式.如果有不满足case条件的枚举值, 10 switch应该总是包含一个default匹配. 对于空循环体应使用{}或continue,而不是一个简单的分号. 1.5空格/空行 μFun的空格使用方式(主要)取决于它是用于函数还是关键字.(大多 数)关键字后要加一个空格。
值得注意的例外是sizeof、typeof、alignof和 __attribute__以及一些编译器自定义扩展的关键字,这些关键字某些程度上看 起来更像函数(它们也常常伴随小括号而使用,尽管在C语言里这样的小括号 11 不是必需的,就像“structfileinfoinfo”声明过后的“sizeofinfo”)。
  所以在这些关键字之后放一个空格: if,switch,case,for,do,while 但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后 放空格。
例如, s=sizeof(structfile); 不要在小括号里的表达式两侧加空格。
这是一个反例: s=sizeof(structfile); 当声明指针类型或者返回指针类型的函数时,“*”的首选使用方式是使之 靠近变量名或者函数名,而不是靠近类型名。
例子: 在大多数二元和三元操作符两侧使用一个空格,例如下面所有这些操作符: 但是一元操作符后不要加空格: &*+‐~!
sizeoftypeofalignof__attribute__defined 后缀自加和自减一元操作符前不加空格: 前缀自加和自减一元操作符后不加空格:12 “.”和“->”结构体成员操作符前后不加空格。
不要在行尾留空白。
有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后你就可以直接在那一行输入代码。
不过假如你最后没有在那一行输入代码,有些编辑器就不会移除已经加入的空白,就像你故意留下一个只有空白的行。
包含行尾空白的行就这样产生了。
另外就是如何合理的使用空行了.很简单,就是将逻辑功能相关的语句放在一起,与不相关的语句用空行隔开.这样非常有助于阅读理解代码意图.  1.6预处理左对齐 即使预处理指令位于缩进代码块中,指令也应从行首开始. 1.4typedef别名 13 不要使用类似“vps_t”之类的东西。
对结构体和指针使用typedef是一个错误。
当你在代码里看到:vps_ta;这代表什么意思呢?相反,如果是这样structvirtual_container*a;你就知道“a”是什么了。
很多人认为typedef“能提高可读性”。
实际不是这样的。
它们只在下列情况下有用:a)完全不透明的对象(这种情况下要主动使用typedef来隐藏这个对象实际 上是什么).例如:“pte_t”等不透明对象,你只能用合适的访问函数来访问它们。
注意!不透明性和“访问函数”本身是不好的。
我们使用pte_t等类型的原因在于真的是完全没有任何共用的可访问信息。
b)清楚的整数类型,如此,这层抽象就可以帮助消除到底是“int”还是“long”的混淆。
u8/u16/u32是完全没有问题的typedef,不过它们更符合类别(d)而不是这里。
再次注意!要这样做,必须事出有因。
如果某个变量是 “unsignedlong“,那么没有必要typedefunsignedlongmyflags_t;不过如果有一个明确的原因,比如它在某种情况下可能会是一个“unsignedint”而在其他情况下可能为“unsignedlong”,那么就不要犹豫,请务必使用typedef。
c)和标准C99类型相同的类型,在某些例外的情况下,虽然让眼睛和脑筋来 14适应新的标准类型比如“uint32_t”不需要花很多时间,可是有些人仍然拒绝使用它们。
因此,Linux特有的等同于标准类型的“u8/u16/u32/u64”类型和它们的有符号类型是被允许的——尽管在你自己的新代码中,它们不是强制要求要使用的。
当编辑已经使用了某个类型集的已有代码时,你应该遵循那些代码中已经做出的选择。
d)可以在用户空间安全使用的类型。
在某些用户空间可见的结构体里,我们不能要求C99类型而且不能用上面提到的“u32”类型。
因此,我们在与用户空间共享的所有结构体中使用__u32和类似的类型。
可能还有其他的情况,不过基本的规则是永远不要使用typedef,除非你可以明确的应用上述某个规则中的一个。
总的来说,如果一个指针或者一个结构体里的元素可以合理的被直接访问到,那么它们就不应该是一个typedef。
 第2章注释规则 参考Linux,加入版权说明 2.0文件注释 2.1函数注释 2.3变量注释 2.4实现注释 15 2.5TODO注释 2.6块注释 If/else/for/while/dowhile/switch 2.7弃用说明注释 第3章变量规则 第4章函数规则 函数应该简短而漂亮,并且只完成一件事情。
函数应该可以一屏或者两屏显示完,只做一件事情,而且把它做好,当然,对于一些底层代码可以根据实际情况作出调整。
遵循的原则就是:高扇入,合理扇出.即尽量多的让自己被别的模块调用而少调用别的模块(<7),扇出过高,说明要考虑的问题就越多,考虑的东西越多,人脑犯错的可能就越大.一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。
所以,如果你有 一个理论上很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很小的事情,这样的函数尽管很长,但也是可以的。
不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能甚至搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。
16使用辅助函数,并为之取个具描述性的名字(如果你觉得它们的性能很重要的话可以让编译器内联它们,这样的效果往往会比你写一个复杂函数的效果要好。
)函数的另外一个衡量标准是本地变量的数量。
此数量不应超过5-10个,否则你的函数就有问题了。
重新考虑一下你的函数,把它分拆成更小的函数。
人的大脑一般可以轻松的同时跟踪7个不同的事物,如果再增多的话,就会糊涂了。
即便你聪颖过人,你也可能会记不清你2个星期前做过的事情。
在源文件里,使用空行隔开不同的函数。
 第5章GitCommit规则 第6章文档规则 17 参考资料: 1)Linux内核代码风格(中文版)2)Linuxkernelcodingstyle(English)3)GoogleC++风格指南-中文版4)GoogleC++StyleGuide(English)5)MISRA-C-2004_工业标准的C编程规范_中文版6)MISRA-2004IARWorkBench版本(英文) 推荐书目: TODO… 18

标签: #位置 #乱码 #迅雷 #文件 #文件夹 #文件 #映像 #文件