破开C暗夜的第一道光(2)——高质量代码风格

  太多人会写代码,却只有极少的程序员可以将代码写出美感,你想让自己的代码成为高质量代码吗?下面这些建议一定可以帮到你。

以下是高质量代码需遵循的建议,下方有优秀代码示例。

一、文件结构

【建议1】为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。

【建议2】用#include <filename.h>格式来引用标准库的头文件(编译器从标准库目录开始搜索)。

【建议3】用#include “filename.h”格式来引用非标准库的头文件(编译器先从用户的工作目录开始搜索,搜不到再到标准库里找,为节省时间引用库函数用<>格式)。

【建议4】头文件中只存放“声明”而不存放“定义”。

二、程序的版式

· 空行

【建议1】每个函数构建完成后在下方都要加一行空行,来与其他语句块分隔开。

【建议2】在一个函数体内,逻辑上密切相连的语句间不加空行,与其他语句间要用一行空格加以分隔。

【建议3】用空格将声明部分和程序其他部分区分开。

· 代码行

【建议1】一行代码只做一件事,如只定义一个变量,或只写一条语句。这样代码易于阅读和写注释。

【建议2】if、else、for、while、do等语句独自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{ }。这样可以防止书写失误。

【建议3】尽可能在定义变量的同时初始化变量。

· 代码行内的空格

【建议1】函数名紧跟左括号 ‘(’,不要留空格;而if、for、while等关键字之后应留一个空格再跟左括号,这样便于区别函数和关键字。

【建议2】逗号 ‘,’之后要留一个空格,分号 ‘;不是一行的结束符号时,其后要留一个空格。

【建议3】赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格。

【建议4】一元操作符如“!”、“~”、“++”、“- -”、“&”(地址运算符)等前后不加空格。

· 对齐

【建议1】程序的分界符 ‘{’ 和 ‘}’ 应独自占一行并且位于同一列,同时与引用
它们的语句左对齐。

【建议2】{ }之内的代码块在 ‘{’ 右边数格处左对齐。

· 长行拆分

【建议1】每一行代码行不要太长。

【建议2】长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要进行适当的缩进,使排版整齐,语句可读。

    //变量千万不要这样定义,这样写只是为了举例
	if ((very_very_long_sentence1>= very_very_long_sentence2)
	  &&(very_very_long_sentence3<= very_very_long_sentence4)
	  &&(very_very_long_sentence5==very_very_long_sentence6))
	//操作符放在新行之首,同时注意对齐
	for (very_very_very_very_long_sentence=0;
		very_very_very_very_long_sentence<10;
		very_very_very_very_long_sentence++)

· 修饰符的位置

【建议1】修饰符 * 和 & 应紧靠变量名

    //y容易被误解为指针
	int* x, y; 
	//此处y不易被误解
	int *x, y;
	//更好的格式应为分行定义
	int *x;
	int y;

· 注释

【建议1】注释是对代码的“提示”,要精简、准确,不要花里胡哨。

【建议2】对复杂或有特殊意义的代码才进行注释,简单语句不注释

【建议3】边写代码边注释,修改代码同时修改相应的注释,无用注释要删除。

下为良好风格的代码:

//一行只定义一个变量并尽量初始化
	int width = 0;
	int depth = 0;
	int height = 0;
//一行只写一个语句,操作符前后各加一个空格
	x = a + b;
	y = c + d;
	z = e + f;
//for与‘(’间留一个空格,‘;’后空一格,操作符前后都空一格
//‘{’和‘}’独占一行且位于同一列,与for左对齐
	for (i = 0; i < 10; i++)
	{
		do_something();
	}
	                   //空一行,与其他语句隔开,一个模块为一部分
	other();

三、命名规则

· 命名规则

【规则1】标识符应直观且可拼读,望文知意。

【规则2】命名风格保持一致。若用“大小写”分隔方式,如AddNumber,就全用该方式;若用“小写加下划线”的方式,如add_number,就只用这种方式,不要将两种方式混用。

【规则3】程序不要出现仅靠大小写区分的相似的标识符

int x, X; //容易混淆,不要这样写

· 命名惯例

函数名首字母大写其余小写

int Add(int x);

#define定义的常量字母全大写

#define MAX 100

静态变量加前缀s_(表示static)

static int s_name; //静态变量

不得不用全局变量,全局变量加前缀g_(表示global)

int g_name; //全局变量

四、表达式和基本语句

· 括号()的使用

若代码行中的运算符较多,要用括号()确定表达式的操作符,防止产生歧义。

· 浮点型变量的比较

浮点型与0或浮点数的比较不能使用“==”或“!=”,应设法转换为“>=”或“<=”的形式。(因为精度缺失的原因)

#include<stdio.h>  //使用以下两个精度,需要包含改头文件。
DBL_EPSILON  //double最小精度
FLT_EPSILON  //float最小精度
float x = 0;
if (x == 1.0) //错误的比较
//应该转化为
if ((x - 1.0) > -FLT_EPSILON && (x - 1.0) < FLT_EPSILON)
//或
if (fabs(x - 1.0) < FLT_EPSILON)

注:fabs是C语言函数库中求绝对值的函数,头文件#include <math.h>。

· 指针比较

指针变量是与NULL(空指针)比较,而不是和0比。

· for循环

不要在for循环内修改循环变量,应在for后()内修改,防止for循环失去控制。

· switch语句

【建议1】每个case语句的结尾不要忘了加break,否则将导致多个分支重叠。(除非有意为之)

【建议2】不管用不用,都最好在代码块的最后加一个default分支,利于以后的修改。

五、函数设计

· 参数规则

如果参数是指针,且仅输入不改值,则应在类型前加const,以防该指针在函数体内被意外修改。

//源字符串不应被修改,用const修饰
char * strcpy(char *destination, const char *source);

· 设计函数的建议

每个函数的功能要单一,不要让一个函数实现多个功能;规模要小,尽量控制在50行代码以内。

· 使用断言

char *clone_string( const char *source )
{
        char *result;
        //使用断言,防止出现使用空指针的情况
        assert( source != NULL );
        ......
}

断言的使用可排除不应发生的非法情况,让程序更稳定。

六、内存管理

· 内存分配

内存分配,极易出错,遵循建议,干掉小错误!
【建议1】用malloc申请完内存后,应立即判断是否申请成功,检查指针是否为空指针

//自定义函数中用断言
assert(p != NULL);
//main函数体中用
if (p == NULL)
//或
if (p != NULL)  //来防错

【建议2】定义数组和申请动态内存是需要赋初值,防止使用了未初始化的内存。

【建议3】当心数组和指针的下标是否发生“多1”或“少1”的操作,避免越界访问。

【建议4】动态内存分配后一定要记得在后面用free将它释放,且内存释放后要立刻将指针设置为空指针,防止产生“野指针”。

int* p = (int*)malloc(40);

if (p == NULL)  //判断内存是否申请成功
{
	printf("%s\n", strerror(errno));
	return 0;
}
	
free(p);  //内存释放
p = NULL;  //置为空指针

申请的动态内存不会自动释放,自己一定不要忘记手动释放,否则动态内存申请的太多而未释放可能导致程序崩溃。

完结

C语言细微的规则还有许多,有的一般的学习者都可避免,有的则太过细小,上面的内容已涉及绝大多数值得注意和学习的规则与建议,相信只要读者将它们完全融会贯通、内化到自己的代码风格中后,一个属于你自己的优秀代码风格诞生啦。别的程序员见到直接顶礼膜拜,面试官直接双手奉上好offer。

继续加油呀,与君共勉!

下接数据与数据类型——标识符与常变量

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遥逖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值