-
C
语言书写规范指南
第
1
章文件结构
每个
C
程序通常分为两个文件。一个文件用于保存程序的声明(
declaration
),称为头文
件。另一个文件用于保存程序的实现(
implementation
),称为定义(
definition
)文件。
C
程序的头文件以“
.h
”为后缀,
C
程序的定义文件以“
.c
”为后缀。
版权和版本的声明
版权和版本的声明位于头文件和定义文件的开头(参见示例
1-1
),主要内容有:
1
)版权信息。
2
)
文件名称,标识符,摘要。
3
)
当前版本号,作者
/
修改者,完成日期。
4
)版本历史信息。
/*
*Copyright
(
c
)
2001,
吉林大学物理学院无线电
*Allrightsreserved.
*
*
文件名称:
*
文件标识:
*
摘
要:
简要描述本文件的内容
*
*
当前版本:
*
作
者:
输入作者(或修改者)名字
*
完成日期:
2007
年
7
月
20
日
亠
*
取代版本:
*
原作者
*
完
:
输入原作者(或修改者)名字
p>
成日期:
20
07
年
5
月
1
0
日
*/
示例
1-1
版权和版本的声明
头文件的结构
头文件由三部分内容组成:
(1)
1
)
。
(2)
预处理块。
(3)
函数和类结构声明等。
假设头文件名称为
,头文件的结构参
见示例
1-2
。
头文件开头处的版权和版本声明
(<
/p>
参见示例
1-
【规则
1-2-1
】为了防止头文件被重复引用,应当用
【规则
1-2-2
】用
#inelude
索
)
。
p>
【规则
1-2-3
】用
#inelude
始搜索
)
。
【规则
1-2-4
】
< br>
#inelude
后面使用
T
AB
键控制排版。
#ifndef/
#define/#endif
结构产生预处理块。
<>
格式来引用标准库的头文件
(
编译器将从标准库目录开始搜
“格式来引用非标准
库的头文件
(
编译器将从用户的工作目录开
【规则
1-2-5
】头文件中只
存放“声明”而不存放“定义”
【规则
1-2-6
】全局变量在头文件中声明,在
.c
文件中定义
.h extern in
tvalue;
声明。
.c in
tvalue=0x10;
定义。
【规则
1-2-7
】局部变量在
.c<
/p>
中定义
(static) unsigned in
tvalue;
定义。
->
”这类操作符前后不加空格。
<
/p>
【建议
2-3-1
】对于表达式比较长的
for
语句和
if
语句,为了紧凑起见可以适当地去掉一些空
格,女口
for(i=0;i<10
;i++)
和
if((a<=b)&&(c<=d))
void Fun c1(i nt x,i nt y,i
nt z);
从左至右
!
?
++-_
+ - * &
* / %
+ -
<< >>
< <= > >=
== !=
&
A
|
&&
II
(
类型
)sizeof
从右至左
从左至右
从左至右
从左至右
从左至右
从左至右
从左至右
从左至右
从左至右
从左至右
从右至左
从右至左
=+=
-=
*=
/=
%=
&=
A =
从左至右
|= <<= >> =
表
4-1
运算符的优先级与结合律
p>
【规则
4-1-1
】如果代码行中的运算符比较多,用括号确定表达式的操作顺序,避免使用默认的
优先级。
由于将表
< br>4-1
熟记是比较困难的,为了防止产生歧义并提高可读性,应当用括号确定表达
式
的操作顺序。
例如:
word = (high<<8)|low
复合表达式
如
a=b=c=0
这样的表达式称为复合表达式。允许复合表达式存在的理由是
: (1)
书写简洁;
(2)
< br>可以提高编译
效率。但要防止滥用复合表达式。
【规则
4-2-1
】不要编写太复杂的复合表
达式。例如:
<
br>
i=a>=b&&c
〃复合表达式过于复杂
【规则
p>
4-2-2
】不要有多用途的复合表达式。例如:
d=(a=b+c)+r;
该表达式既求
a
值又求
d
值。应该拆分
为两个独立的语句
:
a = b + c;
d = a + r;
【规则
4-2
-3
】不要把程序中的复合表达式与“真正的数学表达式”混淆。例如:
if(a
〃
a
是数学表达式而不是程序表达式并不表示
if ((a
而是成了令人费解的
if((a
语句
p>
if
语句是
C
语言
中最简单、最常用的语句,然而很多程序员用隐含错误的方式
写
if
语句。本节以“与零
值比较”为
例,展开讨论。
布尔变量与零值比较
【规则
4-3-1
】不可将布尔变量直
接与
TRUE FALSER
者
1<
/p>
、
0
进行比较。
根据布尔类型的语义,零值为“假”(记为
FALSE
,任何非零值都是“真”(记为
TRUE
。
TRUE
勺值究竟是
什么并没有统一的标准。例如
而
< br>VisualBasic
则将
TRUE
< br>定义为
-1
。
假设布尔变量名字为
flag
,它与零值比较的标准<
/p>
if
语句如下:
if (flag)//
表示
flag
为真
if
(!flag)
〃
表示
flag
为假
其它的用法都属于不良风格,例如:
if(flag==TRUE)
if(flag==1)
if(flag==FALSE)
if(flag==0)
VisualC++
将
TRUE
定义为
1
,
整型变量与零值比较
【规则
4-3-2
】应当将整型变量用“
==
”或“!
=
”直接与
0
比较。假设整型
变量的名字为
p>
value
,它
与零值比较的标准
if
语句如下:
if(value==0) if(value!=0)
不可模仿布尔变量的风格而写成
if(value)
//
会让人误解
value
是布尔变量
if(!value)
浮点变量与零值比较
【规则
4-3-3
】不可将浮点变量用“
==
”或“!
=
”与任何数字比较。
千万要留意,
无论是
float
还是
double<
/p>
类型的变量,都有精度限制。所以一定要避免将浮点变
量用
“
==
”或“!
=
”与数字比较,应该设法转化成“
>=
”或“
<=
”形式。
假设浮点变量的名字为
x,
应当将
if(x==//
隐含错误的比较转化为
if((x>=-EPSINON)&&(x<=EPSINON))
其
中
EPSINOF
是允许的误差
(
即精度
)
。
指针变量与零值比较
【规则<
/p>
4-3-4
】应当将指针变量用
”或
!
=
”与
NULLt
匕较。
指针变量的零值是“空”(记为
if(p==NULL)
if(p!=NULL)
不要写成
if(p==0)
ll
容易让人误解
p
是整型变量
NULL)
。尽管
NULL
的值与
0
相
同,但是两者意义不同。假设
指针变量的名字为
p
,它与零值比较的标准
if
语句如下:
lip
与
NULL
显式比较,强调
p
是指针变量
if(p!=0)
或者
if(p)
if(!p)
ll
容易让人误解
p>
p
是布尔变量
对
if
语句的补充说明
有时候我们可能会看
到
if(NULL==p)
这样古怪的格式。不是程序写错了,
是程序
员为了防止将
if(p==N
ULL)
误写成
if(p=NULL)
,而有意把
p
和
NULL
颠倒。编译器认为
if(p=NULL)
是
合法的,但
是会指出
if(NULL=p)
是错误的,因为
NULL
不能被赋值。
程序中有时会遇到
iflelselreturn
的组合,应该将如下不良风格的程序
if(condition)
returnx;
returny;
改写为
if(condition)
{
returnx;
}
else
{
returny;
}
或者改写成更加简练的
return(conditionx:y);
循环语句的效率
C
< br>循环语句中,
for
语句使用频率最高,
while
语句其次,
do
语
句很少用。本节重点论述循环
体的效率。提
< br>高循环体效率的基本办法是降低循环体的复杂性。
【建议
4-4-1
】在多重循环中,
如果有可能,应当将最长的循环放在最内层,最短的循环
放在最外层,以
减少
CPL
跨切循环层的次数。例如示例
4-4(b)
的效率比示例
4-4(a)
的高。
for (row=0; row<100; row++)
{
for (col=0;
col<5; col++)
{
fum = sum+a[row][col];
}
}
p>
示例
4-4(a)
低效率:长循环在最外层
for (col=0; col<5; col++)
{
for (row=0;
row<100; row++)
{
fum = sum+a[row][col];
}
}
p>
示例
4-4(b)
高效率:长循环在最内层
【建议
4-4-2
】如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体
的外面。示例
4-4(c)
的程序比示
例
4-4(d)
多执行了
N-1
次逻辑判断。并且由于前者老要进行逻辑判
断,打断了
循环“流水线”作业,使得编译器不能对循环进行优化处理,降
低了效率。如果
N
非常大,最好采用示例
4-4(d)
的写法,可以提高效率。如果
N
非常小,两者效率差别并不明显,
采用示例
4-
4(c)
的写法比较好,
因为程序更加简洁。
循环体内修改循环变量,防止
<
br> { <
br>case <
br>
for (i=0; i
{
if
(condition
{
DoSomething();
}
else
{
DoOtherthing();
}
}
表
4-4
(c)
效率低但程序简洁
if(condition)
{
for(i=0;i
}
else
{
for(i=0;i
}
表
4-4
(d)
效率高但程序不简洁
语句的循环控制变量
【规则
4-5-1
】不可在
for
for
循环失去控制。
【建议
4-5-1
】建议
f
or
语句的循环控制变量的取值采用“半开半闭区间”写法。
示例
4-5(a)
中的
x
值属于半开半闭区间“
0=
”,起点到终点的间隔为
N,
循环次数为
N
。
示例
4-5(b)
中的
x
值属于闭区间“
0=
”,起点到终点的间隔为
相比之下,示例
4-5(a)
的写法更加直观,尽管两者的功能是相同的。
p>
for(intx=0;x
N-1
,循环次数为
N
。
}
示例
4-
5(a)
循环变量属于半开半闭区间
for(intx=0;x<=N-1;x++)
{
}
p>
示例
4-5(b)
循环变量属于闭区间
p>
语句
swit
ch
是多分支选择语句,而
if
语句只
有两个分支可供选择。虽然可以用嵌套的
if
语句来实
现多分支选择,但那样的程序冗长难读。这是
switch
语句的基本格式是:
switch(variable)
{
switch
语句存在的理由。
case value1:
{
}
break;
case
value2:
{
break;
}
default:
{
break;
}
}
p>
【规则
4-6-1
】每个
语句的结尾不要忘了加
break
,否则将导致多个分支重叠
(
除
非有意使多个分支
重叠
)
p>
。
【规则
4-6-2
】不要忘记最后那个
default
分支。即使程序真的不需要
default
处理,也应该
保留语句
default:break;
这样做并非多此一举,而是为了防止别人误以为你忘了
default
处
理。
语句
自从提倡结构化设计以来,
goto
就成了有争议的语句。首先,由于
goto
语句可以灵活跳
转,如果不加限制,它的确会破坏结构化设计风格。其次,
goto
语句经常带来错误或隐患。
它可能跳过了某些对象的构造、变量的初始化、重要的计算等语句,例如:
goto
state;
Stri ng
s1,s2; //
被
goto
跳过
int
sum = 0;//
被
goto
跳过
state:
如果编译器不能发觉此类错误,每用一次
goto
语句都可能留下隐患。
p>
很多人建议废除
C
的
goto
语句,以绝后患。但实事求是地说,错误是程序员自己造成的
,
不是
goto
的过
错。
goto
语句至少有一处可显神通,它能
从多重循环体中咻地一下子跳到外
面,用不着写很多次的
break
语
句
;
例如
{
…
{
…
-
-
-
-
-
-
-
-
-
上一篇:商业术语词汇
下一篇:员工的满意度和生产力【外文翻译】