C语言编程规范 — 标识符的命名规则

一、标识符定义规则

1.可以由数字、字母、下划线_、美元符号$组成

2.不能以数字开头

3.不能是关键字

4.区分大小写

二、常用标识符命名风格

1、unix like风格:单词用小写字母,每个单词直接用下划线‘_’分割,例如:text_mutex, kernerl_text_address。

2、小驼峰命名法:

当标识符是一个单词的时候,首字母小写,例如:name。

当标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写,例如:firstName。

3、大驼峰命名法:

当标识符是一个单词的时候,首字母大写,例如:Student。

当标识符由多个单词组成的时候,每个单词的首字母大写,例如:GoodStudent。

4、匈牙利命名法:用这种方法命名的变量显示了数据类型,匈牙利命名主要包括三个部分:基本类型、一个或更多的前缀,一个限定词。这种命名法最初在20世纪80年代的微软公司广泛使用,并在win32API和MFC库中广泛使用,但匈牙利命名法存在较多的争议,不太建议使用该命名法。

三、标识符通用命名规则

原则3.1  标识符的命名要清晰明了,有明确含义,同时能使用完整的单词或被大家基本可以理解的单词缩写,避免使人产生误解。

说明:尽可能给出描述性名称,不要节约空间,让别人很快理解你的代码更重要。

示例:好的命名:

int error_number;
int number_of_completed_connection;

不好的命名:使用模糊的缩写或随意的字符:

int n;
int nerr;
int n_comp_conns;

原则3.2  除了常用的通用缩写以外,不使用单词缩写,不得使用汉语拼音。

说明:较短的单词可通过去掉“元音”形成缩写,较长的单词可取单词的头几个字母形成缩写,一些单词有大家公认的缩写,常用单词的缩写必须统一。协议中单词缩写与协议保持一致。对于某个系统使用的专用缩写应该在注释或者某处做统一处理。

示例:一些常见的可以缩写的例子:

addtion —> add    answer —> ans    array —> arr    average—>ave    argument —> arg

buffer —> buff 或 buf

clock —> clk

column —> col

control —> ctrl

command —> cmd

compare —> cmp

configuration —> cfg

count —> cnt

define —> def    delete —> del    destination—>dst 或 dest    display—>disp    device —> dev    decode —> dec    division —> div

frequency—>freq

error —> err    environment —> env    encode —> enc

hexadecimal —> hex    header —> hdr

index —> idx    image —> img    initialize —> init    increment —> inc    length—>len

make —> mk    maximum —> max    message —> msg    minumum —> min    multiplication—>multi    memory—>mem    middle—>mid

number —> num

option—>opt

parameter —> para    previous —> prev    pointer —> ptr

register —> reg    receiver—>recv    return —> ret    result—>res

source —> src    stack—>stk    string—>str    subtraction—>sub    semaphore —> sem    statistic —> stat    syncchronize —> sync

table —>tab    temp —> tmp    temporary—>tmp或temp    time stamp—>ts

value—>val

规则3.1  产品/项目组内部应保持统一的命名风格。

说明:Unix like和 windows like风格均有其拥趸,产品应根据自己的部署平台,选择其中一种,并在产品内部保持一致。

例外:即使产品之前使用匈牙利命名法,新代码也不应当使用。

建议3.1  用正确的反义词命名具有互斥意义的变量或相反动作的函数。

示例:

add/remove       begin/end              create/destroy    insert/delete    first/last
get/release      increment/decrement    put/get           add/delete
lock/unlock      open/close             min/max           old/new
start/stop       next/previous          source/target     show/hide
send/receiver    source/destination     copy/paste        up/down

建议3.2  尽量避免名字中出现数字编号,除非逻辑上的确需要编号。

错误示例:如下命名,使人产生疑惑。

#define EXAMPLE_0_TEST_
#define EXAMPLE_1_TEST_

正确示例:应改为有意义的单词命名。

#define EXAMPLE_UNIT_TEST_
#define EXAMPLE_ASSERT_TEST_

建议3.3  标识符前不应添加模块、项目、产品、部门的名称作为前缀。

说明:很多已有代码中已经习惯在文件名中增加模块名,这种写法类似匈牙利命名法,导致文件名不可读,并且带来带来如下问题:

  • 第一眼看到的是模块名,而不是真正的文件功能,阻碍阅读;
  • 文件名太长;
  • 文件名和模块绑定,不利于维护和移植。若foo.c进行重构后,从a模块挪到b模块,若foo.c
  • 中有模块名,则需要将文件名从a_module_foo.c改为b_module_foo.c。

建议3.4  平台/驱动等适配代码的标识符命名风格保持和平台/驱动一致。

说明:涉及到外购芯片以及配套的驱动,这部分的代码变动(包括为产品做适配的新增代码),应该保持原有的风格。

建议3.5  重构/修改部分代码时,应保持和原有代码的命名风格一致。

说明:根据源代码现有的风格继续编写代码,有利于保持总体一致。

四、文件命名规则

建议4.1  文件命名统一采用小写规范。

说明:因为不同操作系统对文件名大小写处理会不同(如MS的DOS、Windows系统不区分大小写,但是Linux系统则区分),所以代码文件命名建议统一采用全小写字母命名。多个单词之间使用下划线‘_’分隔。

五、变量命名规则

规则5.1  全局变量应增加 “g_” 前缀。

规则5.2  静态变量应增加 “s_” 前缀。

说明:增加 g_ 前缀或者 s_ 前缀,原因如下:

1、全局变量十分危险,通过前缀使得全局变量更加醒目,促使开发人员对这些变量的使用更加小心。

2、从根本上说,应当尽量不使用全局变量,增加 g_ 和 s_ 前缀,会使得全局变量的名字显得很丑陋,从而促使开发人员尽量少使用全局变量。

慎用全局变量,缺点如下:

1、全局变量破坏了函数的独立性和可移植性,使函数对全局变量产生依赖,存在耦合。

2、全局变量降低了函数代码的可读性和可维护性。

3、在并发环境中,使用全局变量会破坏函数的可重入性,需要增加额外的同步保护处理才能确保数据安全。

规则5.3  禁止使用单字节命名变量,但允许定义 i, j, k 等作为局部循环变量。

建议5.1  不建议使用匈牙利命名法。

说明:变量命名需要说明的是变量的含义,要能达到见名知意的目的,而不是变量的类型。在变量命名前增加类型说明,反而降低了变量的可读性;更麻烦的问题是,如果修改了变量的类型定义,那么所有使用该变量的地方都要修改。

匈牙利命名法是一种编程时的命名规范。基本原则是:变量名=属性+类型+对象描述。匈牙利命名法源于微软,然而却被很多人以讹传讹的使用。而现在即使是微软也不再推荐使用匈牙利命名法。历来对匈牙利命名法的一大诟病,就是导致了变量名难以阅读,这和本规范的指导思想也有冲突,所以本规范特意强调,变量命名不应采用匈牙利命名法,而应该想法使变量名为一个有意义的词或词组,方便代码的阅读。

建议5.2  局部变量的命名采用小驼峰命名法或者Linux内核命名法。使用名词或者形容词+名词方式命名变量。

示例:

//小驼峰命名法
int msgInfo;
int retCode;

//Linux内核命名法
int current_time;

六、函数命名规则

建议6.1  函数建议使用大驼峰命名法或者Linux内核命名法。

示例:

//大驼峰命名法
int EventBaseLoop();
int EventDispatch();

//Linux内核命名法
int event_base_loop();
int event_dsipatch();

建议6.2  函数命名应以函数要执行的动作命名,一般采用动词或者动词+名词的结构。

示例:

int GetCurrentDirectory();

int get_current_directory();

void SetValue(int value);
void set_value(int value);

建议6.3  函数指针除了前缀,其他按照函数的命名规则命名。

七、宏的命名规则

规则7.1  对于数值或者字符串等常量的定义,建议采用全大写的英文字母,单词之间加下划线‘_’的方式命名(枚举常量同样建议使用此方式定义)。

示例:

#define PI_ROUNDED      3.14
#define EVLIST_TIMEOUT	0x01
#define EVLIST_INSERTED	0x02
#define EVLIST_SIGNAL	0x04
#define EVLIST_ACTIVE	0x08
#define EVLIST_INTERNAL	0x10
#define EVLIST_INIT	    0x80
#define LOCAL_IP "127.0.0.1"

规则7.2  除了头文件或者编译开关等特殊标识符定义,宏定义不能使用下划线 ‘_’ 开头和结尾。

说明:一般来说,下划线 ‘_’ 开头、结尾的宏都是一些内部的定义。

示例:

//头文件的宏定义保护,避免被重复包含
#ifndef COMMON_FUN_H_
#define COMMON_FUN_H_
...
#endif

//条件编译的宏定义,可以使用下划线'_'开头
#ifdef _DEBUG
...
#else
...
#endif

八、代码检视问题汇总

判断系统函数的返回值,直接写0即可。

说明:判断系统函数的返回值时,不能调用自定义的宏,确定好系统的返回值之后,直接写0或者-1即可。系统调用函数的返回值,一般情况下都是成功时返回0,失败时返回-1。

行函数命名应使用大驼峰风格或者Linux内核风格。

说明:函数命名应使用大驼峰风格,即:大小写混用,单词连在一起,不同单词间通过单词首字母来分开。也可以使用Linux内核风格的函数命名风格,但是必须要统一,不要二者混用。

结构体类型的定义使用大驼峰命名风格,结构体成员变量则使用小驼峰命名风格或者Linux内核风格。

typede struct {
    int  studNum;       //也可以写成 stud_num
    char gender[10];
    int  age;
    int  grade;
}Student;

指针符号位置

说明:指针符号应该靠近变量。

示例:

//错误写法
int* ptr;
int * ptr;

//正确写法
int *ptr;

复杂的表达式应该使用小括号表明优先级。

说明:存在多个不同的运算符时,为了避免可能存在的优先级问题,要将表达式用小括号括起来。

Log日志打印信息相同不利于分析定位问题。

说明:Log的打印信息可以帮助我们分析定位错误,如果多处的Log打印都一样,就会增加我们定位分析的难度,这不利于我们的开发。

局部变量的命名应使用小驼峰风格。

说明:局部变量的命名应使用小驼峰风格,即:大小写字母混用,单词连在一起,不同单词间通过首字母大写来分开,第一个首字母为小写。当然也可以使用Linux内核风格,但是命名风格需要统一,不要二者混用。

对全局变量的访问应考虑是否需要加锁。

说明:全局变量被多线程访问时,存在数据错误的可能性,在这种情况下,我们要限制线程对全局变量的访问,使得一个线程在访问全局变量时不受其他线程的影响。

代码排版

1、要注意代码排版的空格问题,要去掉多余的空格。

2、数据类型和指针符号(*)之间要有一个空格。例如:

int pInt = (int *)malloc(sizeof(int));

3、一行代码不足120个字符时,不需要换行。

编程规范

1.大括号内两端要留一个空格的空白。

int arr[] = { 1, 2, 3, 4, 5 };

2、函数形参中,不被改变的参数加 const 修饰词。

void func(const int *x, int y);

参考

《华为C语言编程规范(2826-2011.5).pdf》

《华为C&C++安全编程规范_V3.1.pdf》

《高质量C/C++编程指南(林锐-2001).pdf》

华为C语言编程规范(精华总结)

CERT C安全编码规范

你可能感兴趣的:(C语言,C语言,华为C语言编程规范)