本文是AliOS Things提供的一套C语言代码规范,适用的对象为符合C99标准的C语言工程。
本节内容均为建议,不作强制要求。
各种命名均使用英文单词及其缩写,非特殊情况不能使用汉语拼音或其他语言。
(资料图)
文件名全部使用小写字母,用_
连接。 源文件使用.c
后缀。 头文件使用.h
后缀。
2.3.1. 简单类型命名
使用typedef
自定义的简单类型命名全部使用小写字母,用_
连接,以_t
结尾。例如:
typedefint32_taos_status_t;
2.3.2. 结构体和联合体命名
结构体和联合体类型命名全部使用小写字母,用_
连接。建议使用typedef
定义一个整体的名字,以_t
结尾。例如:
typedefstructaos_list_node{structaos_list_node*prev;structaos_list_node*next;}aos_list_node_t;staticaos_list_node_tlist_node;
2.3.3. 枚举命名
枚举类型命名全部使用小写字母,用_
连接。建议使用typedef
定义一个整体的名字,以_t
结尾。 枚举值命名全部使用大写字母,用_
连接,包含表示类型的前缀。 例如:
typedefenumaos_socket_stage{AOS_SOCK_STG_DISCONNECTED,AOS_SOCK_STG_CONNECTED,}aos_socket_stage_t;staticaos_socket_stage_tsock_stage=AOS_SOCK_STG_DISCONNECTED;
变量命名全部使用小写字母,用_
连接。 数组名称尽量使用复数名词。例如:
cfg_file_tcfg_files[NUM_CFG_FILES];
表示数目的变量名称使用num(number的缩写)加复数名词。例如:
unsignedintnum_files;
表示序号的变量名称使用单数名词加num或index或idx(index的缩写)。例如:
unsignedintfile_num;unsignedintfile_index;
函数命名全部使用小写字母,用_
连接。
一般的宏命名全部使用大写字母,用_
连接。例如:
#defineAOS_STRING_MAX_LEN127
模拟函数使用方式的宏的命名规则与函数相同。例如:
#defineaos_dev_set_id(dev,x)\do{\(dev)->id=(x);\}while(0)
为防止命名空间污染,公用组件中的非static函数、非static全局变量、全局类型、全局宏的命名应带有前缀。例如(假设前缀为aos
):
voidaos_cfg_file_close(intfd);externchar**aos_process_argv;typedefstructaos_list_nodeaos_list_node_t;#defineAOS_STRING_MAX_LEN127
源文件、头文件、Makefile等文本文件一律采用UTF-8 without BOM编码,采用Unix风格换行格式。 文本文件末尾应有且只有一个换行符,即末尾应有且只有一个空行。
每行字符数原则上不超过120。包含长路径的#include
语句、头文件#define
保护可以无视此规则。
3.2.1. 表达式换行
较长的表达式可在运算符处换行,换行处的运算符属于旧行,新行对齐到旧行中的相同逻辑层级。例如:
voidfoo(void){if((aos_list_next(list_node)!=&list_head&&!priv)||!(strcmp(symbol,default_symbol)&&blahblahblahblahblahblah()&&meomeomeomeomeomeomeomeomeomeomeomeomeomeomeomeo(NULL))){/*...*/}}
3.2.2. 函数换行
较长的函数定义、声明可在返回值类型和函数名称之间换行。若返回值为指针类型,*
属于新行。例如:
staticunsignedlongblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah(void);staticconstmanager_priv_t*blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah(intindex);
较长的函数定义、声明、调用可在参数列表中间换行,参数列表中间换行后新行应缩进至旧行第一个参数处。例如:
voidblahblahblahblahblahblahblahblahblah(manager_priv_t*priv,intindex,constchar*proc_name);voidfoo(void){blahblahblahblahblahblahblahblahblahblah(get_manager_priv(manager),0,"meomeomeomeomeomeomeomeo");}
3.2.3. 字符串换行
较长的字符串可在空格处换行,一般情况下换行处的空格属于旧行。例如:
voidfoo(void){printf("TheGNUoperatingsystemconsistsofGNUpackages""(programsspecificallyreleasedbytheGNUProject)""aswellasfreesoftwarereleasedbythirdparties.\n");}
使用空格缩进,每次4个空格。全文不应出现制表符(tab)。例如:
voidfoo(unsignedintnbr_processes){unsignedinti;while(i
宏定义、行尾注释、结构体、联合体、枚举等内部可缩进实现多行对齐,但不作强制要求。若有缩进,应对齐到4的整数倍。例如:
/*此处数字0缩进32个字符,即位于第33列。*/#defineSTAGE_UPDATE_CONTINUE0#defineSTAGE_UPDATE_COMPLETE1/*合法*/#defineEVENT_RX_FULL(1U<<0)#defineEVENT_TX_EMPTY(1U<<1)typdefenumsocket_stage{/*此处等号缩进32个字符,即位于第33列。*/SOCK_STG_DISCONNECTED=0,SOCK_STG_CONNECTED=1,}socket_stage_t;/*此处反斜杠缩进40个字符,即位于第41列。*/#defineaos_dev_set_flags(dev,x)\do{\(dev)->flags=(x);\}while(0)/*合法*/#defineaos_dev_set_ops(dev,x)\do{\(dev)->ops=(x);\}while(0)/*此处注释缩进24个字符,即位于第25列。*/foo(NULL);/*abc*/blahblahblahblahblah();/*xyz*//*合法*/foofoofoo();/*abc*/foofoo();/*xyz*/
分行定义的宏,第二行起应缩进一次。例如:
#defineaos_dev_set_id(dev,x)\do{\(dev)->id=(x);\}while(0)
switch
块中的case
语句和default
语句与switch
语句缩进层级相同。例如:
switch(stage){caseSOCK_STG_DISCONNECTED:foo();break;caseSOCK_STG_CONNECTED:sock->connected=1;break;default:break;}
函数体的左花括号另起一行;其他情况下左花括号不另起一行。一般情况下左花括号后续内容另起一行;宏定义中、数组、结构体、联合体初始化时若花括号中内容较短则左花括号后续内容可以不另起一行。 一般情况下右花括号另起一行;宏定义中、数组、结构体、联合体初始化时若花括号中内容较短则右花括号可以不另起一行。右花括号与后续内容组合成一行。 例如:
typedefstructmanager_priv{intindex;void*data;}manager_priv_t;#defineset_manager_index(x,idx)do{(x)->priv->index=(idx);}while(0)#ifdef__cplusplusextern"C"{#endifvoidfoo(void){inti=0;/*...*/if(i==0){/*...*/}else{/*...*/}}manager_priv_tpriv={0,NULL,};#ifdef__cplusplus}#endif
行尾不应有空格。 三元操作符和二元操作符(获取成员的.
和->
操作符除外)前后留有空格。例如:
x=a?b:c;v=w*x+y/z;len=x.length;priv=proc->priv;
一元操作符与参数之间不留空格。例如:
x=*p;p=&x;i++;j=--i;
逗号右侧若有内容,逗号与右侧内容之间应有空格。例如:
voidfoo(intx,inty);
分号右侧若有内容(右圆括号或另外一个分号除外),分号与右侧内容之间应有空格。例如:
for(i=0;i
圆括号内部内容与圆括号之间不留空格。例如:
len=strlen(name);for(i=0;i
圆括号与左侧关键字之间应有空格。例如:
while(1){/*...*/}if(i==0){/*...*/}
圆括号与左侧函数名之间不留空格。例如:
intload_file(constchar*name){foo(0);/*...*/}
类型转换中的圆括号与右侧内容之间不留空格。例如:
manager_priv_t*priv=(manager_priv_t*)p;
方括号与左侧内容、内部内容之间不留空格。例如:
c=name[i];
左花括号左侧或右侧若有内容,左右内容与左花括号之间应有空格。右花括号左侧若有内容,左侧内容与右花括号之间应有空格;右花括号右侧若有内容(分号、逗号除外),右侧内容与右花括号之间应有空格。例如:
#defineset_manager_index(x,idx)do{(x)->priv->index=(idx);}while(0)manager_priv_tpriv={0,NULL,};
分行定义的宏,\
与左侧内容之间应有空格。例如:
#defineset_manager_index(x,idx)\do{\(x)->priv->index=(idx);\}while(0)
指针声明或定义时,*
应靠近变量名称。*
与修饰符之间应有空格。例如:
int*p;constchar*name;void*constptr;void(*func)(void*arg);
十六进制数字A
~F
使用大写形式。 表示二进制的前缀0b
和表示十六进制的0x
使用小写形式。 后缀U
和L
使用大写形式。 后缀f
使用小写形式。 表示幂的e
和p
使用小写形式。 例如:
unsignedintb=0b0101;unsignedintx=0xABCDEF;unsignedintu=0U;longintl=0L;unsignedlongintul=0UL;floatf=1.0f;longdoubleld=1.0L;doubledd=-1.5e-5;doublexd=0xA.Bp12;
使用C90风格的/* */
,不使用C++风格的//
。/*
或*/
与注释正文之间应有空格。行尾的注释和代码之间应有空格。 完整语句注意首字母大写和标点符号,简单词组可以不使用标点。注意区分中英文标点。TODO:使用特定注释格式可利用doxygen等自动化工具生成文档。 例如:
/**ThissourcefileispartofAliOSThings.*ZhangSan*2021.07.01*/ /*ZhangSan*2021.07.01*/ /*ThispointermustNOTbeNULL.*//*connecting*/
为避免与第三方库的头文件命名冲突,公用组件的头文件应存放于子目录中,引用时路径包含子目录名称。例如:
#include
只有包含与本源文件处于同路径中的头文件时使用引号,其他情况均使用尖括号。例如:
#include #include"my_demo.h"
包含头文件的次序如下: |次序 |种类| |-:- |:-| |1 |C语言标准库头文件和工具链头文件| |2 |公用组件的头文件| |3 |本工程头文件|
例如:
#include #include #include#include#include"my_demo.h"
所有头文件都应该使用#define
保护来防止被重复包含。相关宏命名格式是PATH_FILE_H
。 例如,头文件aos/common.h可按如下方法保护:
#ifndefAOS_COMMON_H#defineAOS_COMMON_H/*全部内容*/#endif/*AOS_COMMON_H*/
头文件中的函数声明不使用extern
关键字。头文件中的全局变量声明使用extern
关键字。例如:
voidaos_cfg_file_close(intfd);externchar**aos_process_argv;
公用头文件中声明的函数和全局变量应该使用extern "C"
关键字修饰。#include
不应使用extern "C"
关键字修饰。#define
、类型定义不作要求,可酌情考虑。 例如:
#ifndefAOS_COMMON_H#defineAOS_COMMON_H#include #defineAOS_STRING_MAX_LEN127#defineAOS_LSTRING_MAX_LEN511typedefstructaos_tm{unsignedintsec;unsignedintmin;unsignedinthour;unsignedintmday;unsignedintmon;unsignedintyear;}aos_tm_t;#ifdef__cplusplusextern"C"{#endifexterncharaos_process_symbol[AOS_STRING_MAX_LEN+1];voidaos_start(void);#ifdef__cplusplus}#endif#endif/*AOS_COMMON_H*/
只在本编译单元使用的函数、全局变量应使用static
修饰符。 在不影响功能的前提下,指针类型的函数参数尽量使用const
修饰符。 自增、自减运算符单独使用时采用后置形式。 数组、结构体初始化列表、枚举类型定义中的最后一个成员之后应有逗号。例如:
intoffsets[]={0,1,};
本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
猜你喜欢:
柔性数组在实际项目中的应用?
干货 | protobuf-c之嵌入式平台使用
C语言、嵌入式重点知识:回调函数
实用 | 10分钟教你搭建一个嵌入式web服务器
关键词:
Copyright 2015-2023 非洲礼仪网 版权所有 备案号:沪ICP备2022005074号-8 联系邮箱:58 55 97 3@qq.com