编程跟说话一样,要想言简意赅逻辑清晰,就要学会掌握一定的规则和方法。只有掌握了对应的规则,才能写出优美的程序。这里通过代码留白、代码注释、标识符命名三个方面介绍,如何写出清晰明了的代码。
代码留白
林锐博士,在林锐·高质量C 编程指南之中特别指出了,通过代码留白写出结构松散的代码可以提高代码的易读性。代码留白指恰当的运用空行分隔代码块,用空格分隔开变量和操作符,保持阅读的节奏。
下面介绍一下代码留白的策略,方便大家的使用,避免生搬硬套。
1.在每个类声明之后、每个函数定义结束之后都要加空行
2.在一个函数体内,逻辑密切相关的语句之间不加空行,其他的地方应加空行分隔。
3.一行代码只做一件事情,如只定义一个变量,或只写一句.这样的代码容易阅读,并且方便写注释。
4.if、for、while、do等句自占一行,执行语句不紧跟其后,不论执行语句有多少都要加{}。这样可以防止书写失误。
5.关键字之后要留空格,像const、virtual、inline、case、等关键字之后要至少留一个空格,否则无法辨识关键字。像if、for、while等关键字之后应留一个空格再跟左括号"(",以突出关键字。
6.函数名之后不要留空格,紧跟左括号,以与关键字区别。
7."("向后紧跟,")"、","、";"向前紧跟,紧跟处不留空格。
8.","之后要留空格,如Function(x, y, z)
9.赋值操作符、比较操作符、算术操作符、逻辑操作符、位操作符等二元操作符前后加空格。
10.一元操作符如"!"、"~"、"++"、"--"等前后不加空格
11.像"[]"、"."、"->"这类操作符前后不加空格
12.对于表达式比较长的for语句和if语句,为了紧凑起见可以适当的去掉一些空格
代码示例
void Func1(int x, int y, int z); //Good
void Func1 (int x,int y,int z); //Bad
if ((a>=b) && (c<=d)) //Good
if((a>=b)&&(c<=d)) //Bad
x = a < b ? a : b; //Good
x=a<b?a:b; //Bad
代码注释
为了提高代码的可读性,我们需要对对代码添加适当的注释。注释一般用来阐述对应模块的目的、用途、工作原理、注意事项等代码自身无法"自说明"的东西。为了代码注释的编码兼容性,建议所有的代码采用英文注释。这里建议采用Doxygen的代码注释模式,将来可以直接生成对应的代码API文档,非常方便。
函数的注释如下,主要说明函数的入参和返回值
/**@brief 函数描述
* @param[in] param1 参数1
* @param[in] param2 参数2
* @param[in] param3 参数3
* @ref TYPE1 描述 \n
* @ref TYPE2 描述 \n
* @return 函数执行结果
* - TYPE1 上报成功
* - TYPE2 上报失败
* - Others 其他错误
*/
文件的注释主要说明文件的作用、作者以及版本和注意事项。当然也可以根据自己的需求添加一些说明事项。
/**@file 文件名称
* @brief 文件摘要
* @details 详细描述
* @author 作者及联系方式
* @date 2018-8-17
* @version V1.0
* @copyright Copyright (c) 2018-2020 公司名称
**********************************************************************************
* @attention
* 注意事项1: 事项描述
* 注意事项2:事项描述
* @par 修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>创建时间 <td>版本号 <td>wanghuan <td>版本描述
* </table>
*
**********************************************************************************
*/
结构体注释,主要说明结构体的的含义、以及每个成员的作用。
/**@struct class_struct
* @brief 结构体注释 \n
* 详细描述结构体信息
*/
typedef struct 结构体名字
{
成员1, ///< 成员1注释
成员2, ///< 成员2注释
成员3, ///< 成员3注释
}结构体别名;
行注释主要要说明一下这行的作用
///< 行内容注释
成员命名
如何为项目、文件、类、函数、成员变量起一个简洁易懂的名字,一直是困扰着程序员的一个难题。其实这件事情并不难,主要是对于一些专业词汇的积累。千万不要写一些除了自己谁写不懂的简略缩写和拼音缩写。现在互联网翻译很发达了,上网翻译一下就行。
常见的命名风格,我知道的有三种;
第一种匈牙利命名法,早期的windows上用的很多,变量前面加上i/n/sz等变量头来表明变量的类型。它把变量信息做了"硬编码",不利于反省编程和代码重构,所以现在被淘汰了。不过它的一个做法被延续了下来,给成员变量加"m_"前缀(member),给全局变量加"g_"前缀(global)。这样我们可以直接通过变量名确定变量的作用域。
第二种命名方式叫做驼峰命名法,在Java种很流行,要求单词的首字母大写。
第三种是采用小写的单词,然后单词之间通过下划线连接。这是C/C++的主要命名方式。
我们在编写程序的时候可以集百家之所长,复合应用各种命名规则。
1.在命名成员变量的时候加前缀"m_",在定义全局变量的时候加前缀"g_"
2.定义的类名称采用驼峰命名法,定义成员函数采用下划线连接的小写字母。
3.宏和一些常量采用全大写,单词之间通过下划线连接
4.局部变量可以采用匈牙利命名法通过添加前缀来区别变量的类型。
5.有一个原则:变量/函数的名字长度与它的作用域成正比。也就是说局部变量/局部函数可以短一些,而全局变量/函数名称应该长一些。
小结
编程要掌握一定的规则和节奏,只有这样才能写出结构清晰优美的代码。总的来说有一下三点:
1.代码留白,做好代码空行和空格
2.给文件、类、函数、变量添加合适的注释
3.给文件、类、函数、变量起一个好的名字
参考资料
google_c++编程风格
林锐·高质量C 编程指南
罗剑锋的C++实战笔记