434
社区成员
发帖
与我相关
我的任务
分享华为C语言编程规范(关键点)
代码总体原则
清晰性(可阅读性),简洁性,风格合适
一、头文件
合理的划分头文件、以及头文件之间的包含关系(头文件依赖),从根本上降低编译时间。
(1)头文件中适合放置接口的声明,不适合放置实现。
(2)头文件应当职责单一(减少不必要的展开,减少编译时间)
(3)头文件应向稳定的方向包含
(4)每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。
(5)禁止头文件循环依赖
(6).c/.h文件禁止包含用不到的头文件
(7)头文件应当自包含(任意一个头文件均可独立编译)
(8)总是编写内部#include保护符(#define 保护)
(9)禁止在头文件中定义变量
(10)只能通过包含头文件的方式使用其他.c提供的接口,禁止在.c中通过extern的方式使用外部函数接口、变量(避免声明和定义不一样)
(11)禁止在extern "C"中包含头文件
二、函数
函数设计的精髓:整洁函数,有效组织
(1)一个函数仅完成一件功能
(2)重复代码应该尽可能提炼成函数(降低维护成本)
(3)避免函数过长,新增函数不超过50行(非空非注释行)
(4)避免函数的代码块嵌套过深,新增函数的代码块嵌套不超过4层
(5)可重入函数应避免使用共享变量;若需要使用,则应通过互斥手段(关中断、信号量)对其加以保护。
说明:可重入函数是指可能被多个任务并发调用的函数。共享变量指的全局变量和static变量。
(6)对参数的合法性检查,由调用者负责还是由接口函数负责,应在项目组/模块内应统一规定。缺省由调用者负责。
(7)对函数的错误返回码要全面处理。
(8)设计高扇入,合理扇出(小于7)的函数。
说明:扇出是指一个函数直接调用(控制)其它函数的数目,而扇入是指有多少上级函数调用它。
三、标识符命名与定义
典型的命名风格:
unix like风格:单词用小写字母,每个单词直接用下划线‘_’分割。
Windows风格:大小写字母混用,单词连在一起,每个单词首字母大写。
(1)标识符的命名要清晰、明了,有明确含义。
(2)除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音。
(3)产品/项目组内部应保持统一的命名风格。
(4)文件命名统一采用小写字符。
(5)全局变量应增加“g_”前缀。静态变量应增加“s_”前缀。
(6)禁止使用单字节命名变量,但允许定义i、j、k作为局部循环变量。
(7)对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线‘_’的方式命名。
(8)除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线‘_’开头和结尾。
四、变量
(1)一个变量只有一个功能,不能把一个变量用作多种用途。
(2)结构功能单一;结构的定义应该可以明确的描述一个对象,不要设计面面俱到的数据结构。
(3)不用或者少用全局变量。
(4)防止局部变量与全局变量同名。
(5)通讯过程中使用的结构,必须注意字节序。
(6)严禁使用未经初始化的变量作为右值。
五、宏、常量
(1)用宏定义表达式时,要使用完备的括号。
宏只是简单的代码替换,不会像函数一样先将参数计算后,再传递。
(2)将宏所定义的多条表达式放在大括号中。
注:更好的方法是多条语句写成do while(0)的方式。
(3)使用宏时,不允许参数发生变化。
(4)不允许直接使用魔鬼数字。
解决途径:
六、质量保证
(1)代码质量保证优先原则
(2)要时刻注意易混淆和易用错的操作符。
易混淆:赋值操作符“=” 逻辑操作符“==” 关系操作符“<” 位操作符"<<" 关系操作符“>” 位操作符“>>” 逻辑操作符“||” 位操作符"|" 逻辑操作符“&&” 位操作符"&" 逻辑操作符"!" 位操作符“~”
易用错: 除操作符"/" 求余操作符"%" 自加、自减操作符“++”、“--”
(3)必须了解编译系统的内存分配方式,特别是编译系统对不同类型的变量的内存分配规则,如局部变量在何处分配、静态变量在何处分配等。
(4)不仅关注接口,同样要关注实现。(实现往往会影响接口)
(5)禁止内存操作越界。
内存操作主要是指对数组、指针、内存地址等的操作。
(6)禁止内存泄漏。
(7)禁止引用已经释放的内存空间。
(8)编程时,要防止差1错误。
此类错误一般是由于把“<=”误写成“<”或“>=”误写成“>”等造成的。
(9)所有的if ... else if结构应该由else子句结束;switch语句必须有default分支。
七、程序效率
(1)在保证软件系统的正确性、简洁、可维护性、可靠性及可测性的前提下,提高代码效率。
(2)通过对数据结构、程序算法的优化来提高效率。
八、注释
(1)优秀的代码可以自我解释,不通过注释即可轻易读懂。
(2)注释的内容要清楚、明了,含义准确,防止注释二义性。
(3)在代码的功能、意图层次上进行注释,即注释解释代码难以直接表达的意图,而不是重复描述代码。
(4)修改代码时,维护代码周边的所有注释,以保证注释与代码的一致性。不再有用的注释要删除。
(5)函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等。
(6)全局变量要有较详细的注释,包括对其功能、取值范围以及存取时注意事项等的说明。
(7)注释应放在其代码上方相邻位置或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开,且与下方代码缩进相同。
(8)对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。
(9)避免在注释中使用缩写,除非是业界通用或子系统内标准化的缩写。
九、排版与格式
(1)程序块采用缩进风格编写,每级缩进为4个空格。
宏定义、编译开关、条件预处理语句可以顶格(或使用自定义的排版方案,但产品/模块内必须保持一致)。
(2)相对独立的程序块之间、变量说明之后必须加空行。
(3)一条语句不能过长,如不能拆分需要分行写。一行到底多少字符换行比较合适,产品可以自行确定。
(4)多个短语句(包括赋值语句)不允许写在同一行内,即一行只写一条语句。
(5)if、for、do、while、case、switch、default等语句独占一行。
(6)在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。
十、表达式
(1)表达式的值在标准所允许的任何运算次序下都应该是相同的。
(2)函数调用不要作为另一个函数的参数使用,否则对于代码的调试、阅读都不利。(3)赋值语句不要写在if等语句中,或者作为函数的参数使用。
(4)用括号明确表达式的操作顺序,避免过分依赖默认优先级。
这个星期我阅读了《数学之美》中的第30章——Google大脑和人工神经网络。我认为这本书将人工神经网络这个“高大上”的词讲得非常通俗易懂,让我对人工神经网络有了清晰的认识,下面是我的读书笔记。
人工神经网络依靠超大计算量解决分类问题,是一个形式上非常简单但分类功能将大的机器学习工具。而Google大脑就是一个很能计算的人工神经网络。
1、人工神经网络基本原理
人工神经网络是一个分层的有向图,第一层(输入层)节点(X1,X2,……,Xn)接收输入的信息,来自这些点的数值(x1,x2,……,xn)按照他们输出的弧的权重(w0,w1,w2,……,wn),根据公式(G = w0 + x1*w1 + x2*w2 + …… + xn*wn)进行线性加权(得到G),然后再做一次函数变换F(G)(非线性函数,分类的边界线为曲线),赋给第二层的S,以此类推,逐层向上,直到最后一层(输出层)输出信息。
注:神经元函数:结点的取值用一个非线性函数来计算
规定,神经元函数只能对输入变量(指向它的结点的值)线性组合后的结果进行一次非线性变换。
2、训练人工神经网络(得到模型的参数w1,w2,……,wn)
关键:成本函数的设计=》确定训练出的模型是好是坏
有监督训练(训练数据包含输入和输出数据):比较人工神经网络得到的输出值和实际训练中数据的的输出值之间的差距
无监督训练(训练数据只有输入数据):把每一个样本点到训练出来的聚类中心的欧几里得距离的均值作为成本函数
3、人工神经网络与贝叶斯网络的关系
共同点
(1)都是有向图,每一个节点只取决于前一级的节点。
(2)训练方法相似
(3)对于很多模式分类问题,两种方法在效果上相似,但是效率不同。
(4)训练计算量都特别大
不同点
(1)人工神经网络在结构上是完全标准化的,而贝叶斯网络更加灵活
(2)在神经元函数中,各个变量只能先进行线性组合,再对组合出的结果进行非线性变换。而在贝叶斯网络中,变量可以组合成任意的函数。
(3)贝叶斯网络更容易考虑前后的相关性,可以解码一个输入的序列。而人工神经网络的输出相对孤立,它可以识别一个个字,但是很难处理一个序列。
4、Google大脑的设计原理
(1)并行训练人工神经网络的参数
(2)降低计算量
降低每次迭代的计算量(随机梯度下降法)
减少训练的迭代次数(L-FBGS方法)