怎样编写格式优美的代码
作者:yangw80

很多初学者会被人一眼就看出来是初学者,为什么?原因很多。其中,代码格式是很重要的一项。不注重代码格式,不仅别人看起来不舒服,还会影响自己对代码的阅读。虽然错误的格式不会产生编译错误,但却会让你更容易犯错,并且更难排查错误。所以,学会编写格式优美的代码,是初学者必须要学的一课。

优秀的代码格式并不是唯一的,有很多种风格。本文仅讲解常见的 C/C++ 语言编码规则,而其它规则相信大家在学习工作中会慢慢接触到。

再有就是,为了便于阅读代码,EasyX 网站的代码都是比较注意格式的。所以,如果打算投稿到 EasyX,看看本文也很有必要。

以下讲解编写代码时在格式上一些常见的注意事项。

1. 正确缩进

所谓缩进,是指在某一行代码的左端留出一部分空白。采用缩进的目的为了清楚的定义一个块的开始和结束,这样会使程序更加清晰易读。虽然目前主流的开发平台都具备智能缩进的功能,但是很多时候修改代码还是需要自己注意缩进问题。

下面的范例代码是求解 100 以内的质数,该范例中有多种缩进情况的例子: 

#include <stdio.h>
#include <math.h>

void main()
{
	printf("2");
	int col = 1;

	for (int n = 3; n <= 100; n += 2)
	{
		for (int m = 3; m <= sqrt(n); m += 2)
			if (n % m == 0)
				break;

		if (m > sqrt(n))
			printf("%c%d", (col++ % 5) ? '\t' : '\n', n);
	}

	printf("\n");
}

除此以外,还有很多地方的范例代码有正确缩进,例如 MSDN、VC 自带的范例等。

可以看到,每行代码前的缩进清晰的表明了代码的结构,正确的缩进可以帮助开发者更清晰有效地阅读代码并发现逻辑错误。所以,掌握正确的缩进格式,是编写规范代码的第一课。

2. 学会用 tab 键缩进和对齐代码

当代码中需要缩进时,简单的按一下 tab 键就好。通常一个 tab 符占用 4 个空格的位置。每个 tab 符可以准确的将光标定位到下一个 tab 位,即 4 的整倍数的位置后面。例如,光标在行首时,按 tab 键,光标将会定位到第 4 个字符后面;光标在第 6 个字符后面时,按 tab 键,光标将会定位到第 8 个字符后面。

根据 tab 符的这个特性,除了用来缩进外,tab 键还可以用在很多地方,比如用来对齐代码。下面的范例片段用 tab 符将代码排列得很整齐:

	switch(item)
	{
		case EMPTY:			setfillcolor(BLACK);		break;
		case WALL:			setfillcolor(LIGHTGRAY);	break;
		case PLAYER_A:		setfillcolor(BLUE);			break;
		case PLAYER_B:		setfillcolor(RED);			break;
		case PLAYER_DEAD:	setfillcolor(MAGENTA);		break;
	}

3. 适当增加空行

虽然空行在 C/C++ 语言中没有多大实际的目的,但是通过适当的插入空行能大大提高代码的可读性。一般情况下,在逻辑上相关联的代码块之间会插入一个或多个空行。例如,头文件组、宏定义组、全局变量组之间、两个函数之间,还有函数之间以及函数内部的逻辑片断之间,都可以适当插入空行。插入空行的数量并没有严格规定,而是根据程序的规模和代码风格来适度调整。比如,一个只有 30 行左右的代码,不同的函数间插入一个空行就可以;如果是 300 行左右的代码,可以在函数间插入 3 个空行。

第 1 点的范例代码比较简短,含有少量插入空行的范例。在 EasyX 官网有更多的范例,插入空行的情况也不尽相同。这些需要在学习编程的过程中慢慢体会。

4. 适当增加空格

除了使用空行外,通过使用空格来提高代码的可读性性也是程序员常用的手段。和空行一样,空格的使用也没有强制性的规定,仅仅是为了增强代码的可读性。一般情况下,以下位置可以适当插入空格:

(1) 等号的前后;

(2) 数学运算符的前后,关键字和括号之间插入空格;

(3) 比较运算符的前后;

(4) 后面有代码的分号后面;

(5) 分割不同参数的逗号后面;为了和上下行的代码对齐,有时候需要插入两个空格;如果需要插入更多空格才能和上下代码对齐,通常会使用 tab 键。

5. 适当增加注释

不写注释的编码习惯是不可取的。在较关键的语句、函数或代码片段周围以一定方式增加注释,会令代码简洁易懂,描述清晰的注释可以让阅读代码的人像阅读散文一样舒心。

注释的方式有很多种,以下列举常见的注释方式。

(1) 语句之前的注释,例如:

	// 初始化绘图窗口
	initgraph(640, 480);

(2) 语句右边的注释,例如:

	while(true)
	{
		int cmd = GetCmd();					// 获取用户命令
		if (!DealCmd(cmd))	break;			// 处理命令
		if (!DealGame())	break;			// 处理游戏
		Sleep(200);							// 延时
	}

(3) 语句内的注释,例如:

double springF = SPRINGK /* 弹力系数 */ * (len - SEGLEN);

(4) 代码首部的描述性注释,例如,easyx 官网的很多范例顶部都有这么一段:

///////////////////////////////////////////////////
// 程序名称:xxxxxxxx
// 编译环境:Visual C++ 6.0 / 2010,EasyX_2012立冬版
// 作  者:xxxx <xxxx@xx.com>
// 最后修改:2012-x-xx
//

(5) 函数首部的描述性注释 ,例如:

// 获取用户命令
int GetCmd()
{
    ......
}

(6) 变量后面的描述性注释(对齐注释会更漂亮),例如:

struct Mover
{
	COLORREF	color;			// 颜色
	float		x, 	y;			// 坐标
	float		vX,	vY;			// 速度
};

Phil Haack 曾经说过:“一旦一行代码被敲到文件中, 你就已经要开始维护那一行代码了。”所以,我们自己就是好(或者坏)注释的第一个受益者(或者受害者)。

6. 太长的代码要折行

当一行代码很长的时候(比如函数的参数比较多、判断语句的条件比较多),为了更清晰,可以把一行长代码分成多行书写,例如:

(1) 分行写多个判断语句。看以下代码:

if (ball.x > field.width || ball.x < 0 || ball.y > field.height || ball.y < 0)
{
	......
}

可以分行写成这样(其实这个例子中的代码不算长,不分行也没事,这里只是举个例子):

if (ball.x > field.width || ball.x < 0		// 判断 x 坐标
	|| ball.y > field.height || ball.y < 0)	// 判断 y 坐标
{
	...
}

(2) 分行写多个参数。微软在 MSDN 中的很多例子都是这样做的,例如下面这段摘自 MSDN 的代码

	hwnd = CreateWindow(
		"MainWClass",        // name of window class 
		"Sample",            // title-bar string 
		WS_OVERLAPPEDWINDOW, // top-level window 
		CW_USEDEFAULT,       // default horizontal position 
		CW_USEDEFAULT,       // default vertical position 
		CW_USEDEFAULT,       // default width 
		CW_USEDEFAULT,       // default height 
		(HWND) NULL,         // no owner window 
		(HMENU) NULL,        // use class menu 
		hinstance,           // handle to application instance 
		(LPVOID) NULL);      // no window-creation data 

7. 适当调整代码的表达方式

一些语句功能是相似的,适当将一些语句换一个表达方式,可以令代码更清晰。看以下代码:

ball.x = 320;
ball.y = 240;
if (full)
	ball.color = BLACK;
else
	ball.color = WHITE;
ball.dx = rand() % 6 - 3;
ball.dy = rand() % 6 - 3;

前面这段代码没有错,但是如果修改为下面这样,会更清晰:

ball.x = 320;
ball.y = 240;
ball.color = full ? BLACK : WHITE;
ball.dx = rand() % 6 - 3;
ball.dy = rand() % 6 - 3;

8. 习惯很重要

代码的格式不是要最后修改,而是要在书写代码的时候就写正确。包括注释,都要在写代码的同时就写注释,甚至还可以先写注释然后补充代码。但是,一定不要在写完代码后再补充注释。

结束

编码习惯是一种感觉,只有经常写代码、经常和伙伴们分享代码,才能熟练掌握,运用自如。

更新时间:2012/9/7