看到别人的编写的代码规范非常羡慕,于是也整理总结一份属于自己的编码风格,用于规范自己的代码,增强可读性,非标准规范。强制自己形成良好的编码风格,有利于开发大规模程序而不显得杂乱。 参考stm32固件库编码风格和freertos编码风格。
一、工程文件组织结构
新建工程文件应包含以下全部或部分文件夹:
·usrsrc:用户源文件,用来存放.c文件和其他的源文件。main.c应放在这里。
·usrinc:用户头文件,用来存放.h文件。
·usrdoc:用户说明文档,用来存放用户在开发过程中书写的文档,一般为.txt格式。例如readme.txt,指令说明等。
·src:引用库的源文件。
·inc:应用库的头文件。
·lib:引用的库文件。一个工程一定要包含一个main.c文件,只用来存放main函数。其余函数的定义应在相应的.c文件中,声明在相应的.h文件中。
源文件
·文件头,文件的简介
/*************************************************************************
* copyright (c) 2017, jimbo zhang
* all rights reserved.
*
* file name : usb_ctrl.c
* brief : usb api source code.
* introduce the main function or content of this document briefly.
* revision : 1.01
* author : jimbo zhang
* date : 2017.03.10
* update : introduce the difference from previous version.*************************************************************************/
·必要的注释和说明源文件应该只包含它自己的头文件,其他的头文件在他自己的头文件中包含。源文件中只声明局部函数,全局函数在头文件中声明。全局变量在相应的源文件中定义,在头文件中用extern声明。类型定义在头文件中定义。
/* includes -----------------------------------------------------------*/
/*only include it's own header file, theothers header fileincluded byusb_ctrl.h*/#include usb_ctrl.h
/* declaration --------------------------------------------------------*/
/*here are thelocalfunction declare, globalfuction declare inheader file.*/
void delay( uint32_t n);
/* global variable ----------------------------------------------------*/
·函数头
/******************************************************* brief : delay n ms* parameter : * n: the number of delay microsecond.* return : none.*******************************************************/
void delay( uint32_t n)
{for( i=0; i<110; i++) ;
}
头文件
·文件头,文件的简介
/*************************************************************************
- copyright (c) 2017, jimbo zhang
- all rights reserved.
-
- file name : usb_ctrl.h
- brief : the header file of usb_ctrl.c.
- revision : 1.01
- author : jimbo zhang
- date : 2017.03.10
- update : introduce the difference from previous version.*************************************************************************/
·必要的注释和声明
/* includes -----------------------------------------------------------*/
/* define -------------------------------------------------------------*/
/* typedef ------------------------------------------------------------*/typedefunsignedintapistatus; //api return code
/* enume --------------------------------------------------------------*/
/* extern -------------------------------------------------------------*/
/* declaration --------------------------------------------------------*/
命名规则
参考freertos命名规则,misra c规范。- 定义变量时尽量使用uint8_t 、uint16_t 、uint32_t等。头文件为stdint.h。
typedefsignedcharint8_t;typedefshortint16_t;typedefintint32_t;typedeflonglongint64_t;typedefunsignedcharuint8_t;typedefunsignedshortuint16_t;typedefunsignedintuint32_t;typedefunsignedlonglonguint64_t;
·uint32_t类型的变量使用前缀ul,这里’u’表示’unsigned’,’l’表示’long’
·uint16_t类型的变量使用前缀us,这里’u’表示’unsigned’,’s’表示’short’
·uint8_t类型的变量使用前缀uc,这里’u’表示’unsigned’,’c’表示’char’
·枚举类型变量使用前缀e
·指针类型变量在类型基础上附加前缀p,比如指向uint16_t的指针变量前缀为pus
·与misra指南一致,char类型变量仅被允许保存ascii字符,前缀为c
·与misra指南一致,char *类型变量仅允许指向ascii字符串,前缀为pc
·宏定义全部使用大写,两个单词之间用下划线隔开。
·具有文件作用域的对象尽量声名为static的。
·全局变量加前缀’g_’。整个工程都可以用的变量,不局限于文件作用域。
代码风格
·缩进:缩进使用制表符,一个制表符等于4个空格。
·注释:注释单行不超过80列,特殊情况除外。
·布局:源代码应被设计成尽可能的易于查看和阅读。
下面的代码片中,第一部分展示文件布局,第二部分展示c代码设计格式。
/* #defines, 在合理的位置添加括号. */#define a_definition ( 1 )
/*
* 随后是static (文件内部的)函数原型,
* 如果注释有多行,参照本条注释风格---每一行都以’*’起始.
*/staticvoidprvafunction( uint32_t ulparameter );
/* 文件作用域变量(本文件内部使用),要在函数体定义之前. */staticbasetype_t xmyvariable.
/* 每一个函数的结束都有一行破折号,破折号与下面的第一个函数之间留一行空白。*/
/*-----------------------------------------------------------*/
voidvafunction( void)
{
/* 函数体在此定义,注意要用大括号括住 */
} /*-----------------------------------------------------------*/
staticubasetype_t prvnextfunction( void)
{
/* 函数体在此定义. */
} /*-----------------------------------------------------------*/
/*
* 函数名字总是占一行,包括返回类型。 左括号之前没有空格左括号之后有一个空格,
* 每个参数后面有一个空格,参数的命名应该具有一定的描述性.
*/voidvanexamplefunction( longlparameter1, unsignedshortusparameter2 )
{ /* 变量声明没有缩进. */
uint8_t ucbyte;
/* 代码要对齐. 大括号占独自一行. */
for( ucbyte = 0u; ucbyte < filebuffer_length; ucbyte++ )
{
/* 这里再次缩进. */
}
}
/*
* for、while、do、if结构具有相似的模式。这些关键字和左括号之间没有空格。
* 左括号之后有一个空格,右括号前面也有一个空格,每个分号后面有一个空格。
* 每个运算符的前后各一个空格。使用圆括号明确运算符的优先级。不允许有0
* 以外的数字(魔鬼数)出现,必要时将这些数字换成能表示出数字含义的常量或
* 宏定义。
*/for( ucbyte = 0u; ucbyte < filebuffer_length; ucbyte++ )
{
}
while( ucbyte < filebuffer_length )
{
}
/*
* 由于运算符优先级的复杂性,我们不能相信自己对运算符优先级时刻保持警惕
* 并能正确的使用,因此对于多个表达式运算时,使用括号明确优先级顺序
*/if( ( ucbyte uxtcbnumber = uxtasknumber;
} #endif
/*方括号前后各留一个空格*/
ucbuffer[ 0] = 0u;
ucbuffer[ filebuffer_length - 1u] = 0u;
编程思想
·将特定功能的代码封装成函数。
c语言编程规则
参考misra
·rule1:不得使用三元操作符(? : )。
·rule2:不得残留被注释掉的废代码。
·rule3:所有标识符不超过31字符。
·
rule4:不同名空间中的变量名不得相同。例如:typedef struct mystruct {... } mystruct; (违规)
·
struct person {
char* name;
...
};
char name[32]; (违规)
·rule5: 不得使用char, int, float, double, long等基本类型,应该用stdint.h中定义的类型显示表示类型的大小,如uint16_t、int32_t等。
·rule6:禁止使用八进制数。(因为086u这样的常数很容易引起误解)。
·rule7:不得定义与外部作用域中某个标识符同名的对象,以避免遮盖外部作用域中的标识符。
·rule8:具有文件作用域的对象尽量声名为static的。
·rule9:自动对象(栈对象)使用前必须赋初值。
·
rule10:操作符&&和||的右侧表达式不得具有副作用(side-effect)。也就是说,象 if (x == 20 && ++y == 19)这样的表达式被禁止。
·
·
rule11:不得对有符号数施加位操作,例如 1 << 4 将被禁止,必须写 1ul << 4。
·
·rule12:不得对有副作用的表达式施加sizeof操作符。
·rule13: 除了循环控制语句,不得使用逗号表达式。
·rule14:不得显式判断浮点数的相等性和不等性。
·rule15:不得遗留“永远不会用到”的代码。
·rule16:除了switch语句,不得使用标号(label)。
·rule17:不得使用goto。
·rule18:不得使用continue。
·rule19:除了switch语句,不得使用break
·rule20:if, else if, else, while, do..while, for语句块必须使用{}括起。
·rule21:循环计数器的值不得在循环体内修改。
·rule22:禁止任何直接和间接的递归函数调用。
·rule23:不应该使用#undef。
·rule24:不得将宏作为参数传给宏函数。
·rule25:在一个宏定义中,#或##符号只能出现一次。
·rule26:禁止指针运算(代之以数组下标运算)。
·rule27:禁止超过两级的指针。
·rule28:禁止使用指向函数的非常量指针。
·rule29:禁止使用setjmp, longjmp。
·rule30:禁止使用atoi, atof, atol。(这个我很赞成,建议使用strtol, strtod等函数)
·rule31:禁止使用abort, exit, getenv。
指纹识别和传统密码谁的安全性更高
这次ARM和Micro:bit一起助力蓝宙称霸STEM教育
定量电磁流量计的功能是什么?
诺基亚发飙!一口气发布诺基亚6、诺基亚5、诺基亚3 ,唯独不见诺基亚8
基于AT89C52单片机的智能环保小车电路模块设计
整理总结一份属于自己的编码风格
安森美半导体:芯片短缺下半年将缓解
充电桩功率是多少,汽车充电桩功率的介绍
服务器与PC机的比较
罗姆抢镜高交会:LED智能照明、无线供电
华为通过英国国家网络安全中心测试
华为在构建智能世界过程中的定位、战略和具体措施
iOS13和macOS10.15将有望在WWDC2019亮相
Xilinx Vivado使用增量实现
高速公路变脸催生车载电子导航仪变革
福特下一代电动汽车将于2025年落地
运动跑步耳机哪种最好、好用的跑步耳机推荐
如何调节表观遗传状态和细胞重编程
2021年OPPO开发者大会直播开启
2020年是“AI+物流”应用元年