大型游戏公司内部的编码规范(转载)

大型游戏公司内部的编码规范

 (转载自立仔空间: http://vzzllblog.bokee.com/4718276.html  

说明:这是公司里数以千计的开发人员必须遵守的规则,不是教条。
自由发挥的编程风格只适用于手工作坊、几个人的小公司,对于需要数以十计、百计的技术人员协作的项目,更需要工程化的规定。每个人确实是一颗小螺丝了,也许有些残酷,但是事实就是这样的。

.排版
1.1
规则:程序块应采用缩进风格编写,缩进的空格数为4个。
说明:对于由开发工具自动生成的代码可以有不一致。
1.2
规则:相对独立的程序块之间、变量说明之后应加空行。
示例:如下例子不符合规范。
if( DD_OK != lpSurface->Flip() )
{
  ... // program code
}
sprite++;
waitTime(30);

应如下书写
if( DD_OK != lpSurface->Flip() )
{
  ... // program code
}

sprite++;
waitTime(30);
1.3
规则:较长的语句(>80字符)要分成多行书写。
长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。
示例:
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE
                | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
videoBuffer[x+indexX+(y+indexY)*pitch] = bitmapBufferOffset
+ bitmap[indexX+indexY*bitmapWidth]
1.4
规则:循环、判断等语句中若有较长的语句,则应进行适应的划分。
应首先考虑在分号处划分新行,其次长表达式要在低优先级操作符处划分新行,操作符放在新行之首。
示例:
if( (NULL != backSurface ))
  && (NULL != primarySurface)))
{
  ... // program code
}

for(i = 0, j = 0; (i < back[pixel].Width) && (j < back[pixel].Height);
i++, j++)
{
  ... // program code
}

for(i = 0, j = 0;
    (i < backBufferWidth) && (j < backBufferHeight);
    i++, j++)
{
  ... // program code
}
1.5
规则:若函数或过程中的参数较长,则应进行适当的划分。
示例:
createDirectDraw(NULL,(void**) &pDirectDraw,
            IID_IdirectDraw7, NULL);

PDirectDraw->CreatePalette( DDPCAPS_8BIT | DDPCAPS_ALLOW256
| DDPCAPS_INITIALIZE, palette,&pddpal,NULL );
1.6
规则:一行只写一条语句。
示例:如下例子不符合规范。
rect.length = 0; rect.width = 0;

应如下书写
rect.length = 0;
rect.width = 0;
1.7
规则:条件判断语句语句应独占一行,且主判断语句的执行语句部分需加块符号。
C/C++中的条件语句iffordowhilecaseswitchdefault等都应按此规则排版(其中iffordowhileswitch为主判断语句)。
示例:如下例子不符合规范。
if(NULL == backBuffer) return;

应如下书写:
if(NULL == backBuffer)
{
  return;
}
1.8
推荐:对齐只使用TAB键,不使用空格键。
说明:目前绝大多数编辑器都支持TAB键长度调整,此时应将TAB键长度设置为4;而空格键操作较为繁琐,而且在使用键盘时有所不便,应尽量避免使用空格键来进行对齐操作。
1.9
规则:程序块中的代码应采用缩进风格。
这里的程序块包括函数、过程、方法、数据结构定义、循环体、判断体、case语句体等。
示例:如下例子不符合规范。
void exampleFun( int errCOde )
{
for (...)
{
loop ++;
  ... // program code
}


int first = 0;
switch( errCode )
{
case DDERR_SURFACELOST:
drawSurface->restore();
break;
case ...
}
  ... // program code
}

应如下书写。
void exampleFun( int errCOde )
{
for (...)
{
loop ++;
  ... // program code
}

int first = 0;

switch( errCode )
{
case DDERR_SURFACELOST:
drawSurface->restore();
break;
case ...
}

  ... // program code
}
1.10
规则:程序块的分界符应各独占一行并与引用它们的语句左对齐。
在函数体的开始、类的定义、结构的定义、枚举的定义以及iffordowhileswitchcase语句中的程序都要采用如上的缩进方式。
示例:如下例子不符合规范。
for(...) {
  ... // program code
}

if(...)
  {
  ... // program code
  }

void exampleFun( void )
  {
  ... // program code
  }

应如下书写。
for(...)
{
  ... // program code
}

if(...)
{
  ... // program code
}

void exampleFun( void )
{
  ... // program code
}
1.11
规则:说明性文件中对来自不同源代码文件中的说明应分块进行。
1.12
规则:进行相关赋值或者初始化时,应进行字段对齐。
如对关系较为紧密的结构成员、数组、宏进行定义初始化时,要进行字段对齐。
示例:
struct BufferManager msgBuf[]=
{
{ LockSize, 54, NULL, 0, 0, 0 },
{ LockSize, 280,   NULL
0, 0, 0 },
{ LockSize, 10,   NULL, 0, 0, 0 },
{ LockSize, 10, NULL, 0, 0, 0 }
};

rect.top = 0;
rect.left = 0;
rect.right = 300;
rect.bottom = 200;

#define MaxScrnWidth 640
#define MaxScrnHeight 480
1.13
推荐:在语句中间添加适量空格,以使得代码更清晰。
在两个以上的关键字、变量、常量进行对等操作时,操作符前后要加空格;进行非对等操作时,如果是关系密切的操作符(如类中的.->),后不应加空格。采用这种松散方式编写代码的目的是使代码更加清晰。
由于留空格所产生的清晰性是相对的,所以,在已经非常清晰的语句中没有必要再留空格,如果语句已足够清晰则括号内侧(即左括号后面和右括号前面)不需要加空格,多重括号间可以不加空格,因为在C/C++语言中括号已经是最清晰的标志了。
在长语句中,如果需要加的空格非常多,那么应该保持整体清晰,而在局部不加空格。给操作符留空格时不要连续留两个以上空格。

示例:
(1)
逗号、分号只在后面加空格。
int a, b, c;

(2)
比较操作符, 赋值操作符"=" "+=",算术操作符"+""%",逻辑操作符"&&""&",位域操作符"<<""^"等双目操作符的前后加空格。
if (timeTicks >= MaxTicks)
{
timeTicks = 0;
  ... // program code
}

(3)"!"
"~""++""--""&"(地址运算符)等单目操作符前后不加空格。
*p = 'a';       //
内容操作"*"与内容之间
flag = !isEmpty; //
非操作"!"与内容之间
p = &mem;       //
地址操作"&" 与内容之间
i++;         // "++","--"
与内容之间

(4)"->"
"."前后不加空格。
lpDraw->id = pid; // "->"
指针前后不加空格

(5) if
forwhileswitch等与后面的括号间可以加空格,使if等关键字更为突出、明显;也可以不加空格,使得if等关键字与条件联系更紧密。无论如何,开发人员只应选择其中一种形式,并在同一产品开发中保持一致的风格。
if ( a>=b && c>d )
或者
if( a>=b && c>d )

(6)
ifforwhileswitch等语句,如为多条件组合形式,条件内部可以不加空格,以使各条件更明确。
if ( lines>=height && chars>width && size>maxSize )
1.14
推荐:一行程序以小于80字符为宜,不要写得过长。
考虑在大多数情况下一行程序在屏幕显示时的可见性,一行程序不宜过长,目前建议不大于80个字符。
.注释
2.1
推荐:一般情况下,源程序有效注释量应在20%~40%之间。
注释的原则是有助于对程序的阅读理解。
对于重点函数/方法的解释,和函数/方法中关键算法、复杂操作或者与特定内容相关的程序部分,以及看来显然不合理的(但是实际上是合理的)程序部分,应给出清楚、简洁的注释。
如果本身已经比较清楚的程序部分,不宜再进行注释。过多的注释反而会降低程序的可读性。
本规则推荐在源程序的注释量,并非强制要求。然而在通常情况下,大多数源程序的有效注释量应在此范围内。
2.2
规则:说明性文件头部应进行注释。
说明性文件(如头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)的注释应列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。
示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。
/*************************************************
Copyright (C), 1988.1999, XXXX Tech. Co., Ltd.
File name:     //
文件名
Author:    
Version:    
Date: //
作者、版本及完成日期
Description:   //
用于详细说明此程序文件完成的主要功能,与其他模块
            //
或函数的接口,输出值、取值范围、含义及参数间的控
            //
制、顺序、独立或依赖等关系
Others:       //
其它内容的说明
Function List:   //
主要函数列表,每条记录应包括函数名及功能简要说明
  1. ....
History:       //
修改历史记录列表,每条修改记录应包括修改日期、修改者及修改内容简述
  1. Date:
    Author:
    Modification:
  2. ...
*************************************************/
2.3
规则:源文件头部应进行注释。
源文件头部应列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。
示例:下面这段源文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。
/************************************************************
Copyright (C), 1988.1999, XXXX Tech. Co., Ltd.
FileName: test.cpp
Author:     Version :       Date:
Description:   //
模块描述    
Version:       //
版本信息
Function List:   //
主要函数及其功能
  1. -------
History:       //
历史修改记录
       
    David   96/10/12   1.0   build this moudle
***********************************************************/
说明:Description一项描述本文件的内容、功能、内部各部分之间的关系及本文件与其它文件关系等。History是修改历史记录列表,每条修改记录应包括修改日期、修改者及修改内容简述。
2.4
规则:函数头部应进行注释。
函数注释要列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。
对于简单、自说明的函数可以不做出全面的注释。
示例:下面这段函数的注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。
/*************************************************
Function:     //
函数名称
Description:   //
函数功能、性能等的描述
Calls:       //
被本函数调用的函数清单
Called By:     //
调用本函数的函数清单
Table Accessed: //
被访问的表(此项仅对于牵扯到数据库操作的程序)
Table Updated: //
被修改的表(此项仅对于牵扯到数据库操作的程序)
Input:       //
输入参数说明,包括每个参数的作
            //
用、取值说明及参数间关系。
Output:       //
对输出参数的说明。
Return:       //
函数返回值的说明
Others:       //
其它说明
*************************************************/
2.5
推荐:边写代码边写注释。
修改代码的同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。
2.6
规则:注释的内容应清楚、明了,含义准确,防止注释二义性。
错误的注释不但无益反而有害。
2.7
规则:避免在注释中使用缩写,特别是非常用缩写。
如确需使用缩写,在使用缩写之前,应对缩写进行必要的说明;标准的缩写(如国家标准、行业标准、企业标准),可以在注释中使用,此时仍然建议对缩写进行必要的说明。
2.8
规则:注释应与其描述的代码紧邻。
对代码的注释应放在其紧上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于紧上方则需与其上面的代码用空行隔开。如放于右方且有多条注释相邻,各注释应对齐。
示例:如下例子不符合规范。
/*
初始化鼠标输入设备,并设置为相对坐标方式 */

LPDIRECTINPUT8 pDi;//DX
输入
IDIRECTINPUTDEVICE8 mouse;//
鼠标输入设备
initDirectDraw();
pDi->CreateDevice(GUID_SysMouse, &mouse, NULL);
mouse->SetCooperativeLevel(mainWndHwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
mouse->SetDataFormat(&c_dfDIMouse);
mouse->Acquire();
initKeyboard();

应如下书写
initDirectDraw();

LPDIRECTINPUT8 pDi; //DX
输入
IDIRECTINPUTDEVICE8 mouse; //
鼠标输入设备

/*
初始化鼠标输入设备,并设置为相对坐标方式 */
pDi->CreateDevice(GUID_SysMouse, &mouse, NULL);
mouse->SetCooperativeLevel(mainWndHwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
mouse->SetDataFormat(&c_dfDIMouse);
mouse->Acquire();

initKeyboard();
2.9
规则:对于特定含义的标识符,如其命名不是充分自说明的,声明时应加以注释。
变量、常量、宏的注释应放在其紧上方相邻位置或右方。
示例:
/*
精灵总数 */
#define MaxSprite 1000

#define MaxSurface 1000 /* Ddraw
表面总数 */
2.10
规则:数据结构声明,如其命名不是充分自说明的,声明时应加以注释。
对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方。
示例:可按如下形式说明枚举/数据/联合结构。
/*
16色下颜色代码 */
enum COLOR
{
  BLACK, /*
黑色 */
RED,   /*
红色 */
...
  WHITE, /*
白色*/
};
2.11
规则:全局变量应有较详细的注释。
包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。
示例:
/*
当函数失败时返回错误码,保存在全局变量errCode */ // 变量作用、含义
/* errCode
为不等于0的任意长整数;具体数值由开发工具确定*/   // 变量取值范围
/* errCode
仅供errman.cpp调用 */   // 使用方法
LONG errCode;
2.12
规则:注释与所描述内容应进行同样的缩排。
说明:可使程序排版整齐,并方便注释的阅读与理解。
示例:如下例子,排版不整齐,阅读稍感不方便。
void fun( void )
{
/* code one comments */
  CodeBlock One

    /* code two comments */
  CodeBlock Two
}

应改为如下布局。
void fun( void )
{
  /* code one comments */
  CodeBlock One

  /* code two comments */
  CodeBlock Two
}
2.13
推荐:对重要变量的定义和分支语句(条件分支、循环语句等)应编写注释。
说明:这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好的理解程序,有时甚至优于看设计文档。
2.14
规则:不中断的case语句应加注释。
对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。这样比较清楚程序编写者的意图,有效防止无故遗漏break语句。本规则是 2.2.1 的细化。
示例:
case DIK_DOWN:
  ProcessDown();
  break;
case DIK_RIGHT:
  ProcessRight();
ProcessCFW_B();
//
不要break出去,因为还要处理向前行走的逻辑
case DIK_END:  
  ProcessEnd();  
  break;
...
2.15
推荐:避免在一行代码或表达式的中间插入注释。
说明:除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差。
2.16
推荐:对程序单元应进行正确的命名以及合理组织代码的结构,使代码自说明。
说明:清晰准确的函数、过程、结果、变量等的命名,可增加代码可读性,并减少不必要的注释。
2.17
推荐:应在代码的功能、意图层次上进行注释,提供有用、额外的信息。
说明:注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。本规则是2.2.1的细化。
示例:如下注释意义不大。
/*
如果receiveFlag设置为true */
if( receiveFlag )
...
而如下的注释则给出了额外有用的信息。
/*
如果收到其它精灵的消息 */
if( receiveFlag )
...
2.18
推荐:应在程序块的结束行右方加注释标记,以表明某程序块的结束。
说明:当代码段较长,特别是多重嵌套时,这样做可以使代码更清晰,更便于阅读。
示例:参见如下例子。
if(...)
{
  // program code

  while(index < MaxSprite)
  {
    // program code
  } /* end of while(index < MaxSprite) */ //
指明该条while语句结束
} /* end of if (...)*/ //
指明是哪条if语句结束
2.19
推荐:注释应考虑程序易读及外观排版的因素。
注释语言不统一,影响程序易读性和外观排版,使用的语言若是中、英兼有的,建议使用中文。

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值