遵守参数传递的星号规则。
在C 中,只有当赋值语句中的变元前面带有“*”号时,才能
从子程序中把这个变元传递回来。不管你在说明中堆积了多少个星号,如果你想让某一值传回的
话,那么在赋值语句中至少要有一个星号。例如,在下面的这个程序段中,赋给parameter的
值就不是被传回调用程序的.因为在赋值语句中一个星号也没有:
void TryToPassBackAValue( int * parameter )
{
parameter= SOME_VALUE;
}
而在下面的这个程序段中,赋给parameter的值就是被传回来的,因为在给parameter赋值
的语句中,parameter前面带有一个星号:
void TryToPassBackAValue(int * parameter)
{
*parameter = SOME_VALUE;
}
全局变量的跨度和存活时间都相当之大,
这是为何要避免用全局变量的重要原因之一。
怎样降低使用全局数据的危险
建立使你一眼即可识别出全局变量的命名约定。如果使用全局变量的操作是十分明显的,
可以避免许多错误。如果不只是出于一个目的使用全局变量(如既作为变量又用替换命名常量),
那一定要保证命名约定可以区分这些不同目的。
建立一个清楚标出所有全局变量的注释表。建立标识全局变量的命名约定,对表明变量的
功用是非常有帮助的,而一个标有所有全局变量的注释表则是读你程序的人最强有力的辅助具
之一(Glass 1982)。
全局变量
· 是否是在迫不得已的情况下,才使某些变量成为全局的?
· 命名约定是否对局部、模块和全局变量进行了区分?
· 是否说明了所有全局变量?
· 程序中不该含有伪全局变量——传往各个子程序的庞大而臃肿的数据结构?
· 是否用存取子程序来代替了全局数据?
· 是把存取子程序和数据组织成模块而不是随意归成一堆的吗?
· 存取子程序的抽象层次是否超过了程序语言实现细节?
· 所有相互有联系的存取子程序,其抽象程度都是一致的吗?
并不是因为全局数据危险才避免使用它们,之所以避免用它是因为可以用更好的技术
来代替它。
· 如果全局数据确实不可避免的话,应通过存取子程序来对其进行存取操作。存取子程
序不仅具备全局变量和全部功能,而且可以提供更多的功能。
为了补偿语言的弱点。如果语言中不具备某种定义好的类型,可以自己定义它。例如,
C 中不含逻辑类型,通过建立你自己的类型,很容易弥补这个缺点:
typedef int Boolean_t;
如果必要的话,立自己的逻辑类型。某些语言如Pascal,含有已经定义的逻辑类型。而C
等语言则没有。在像C 这种语言中,可以定义自己的逻辑类型。在C 中,你可以像这样来作:
typedef int BOOLEAN; /* define the boolean type */
把变量说明为BOOLEAN而不是int,可以使得使用它们的意图更清楚,并且在某种程度上
使程序成为自说明的
多设计子程序
提高程序质量的一条标准就是模块化;多设计些好的子程序。程序中有变化时,模块化就方
便得多。如果程序中某一段编成子模块会使之更清晰,就再划出子模块。
隐含全局变量。
如果需要使用全局变量,也可以像前述那样把它隐含起来、通过存取子程
序来使用全局变量有如下优点:不必改变程序就改变数据结构;监视对数据的访问;使用存取
子程序的约束还可以鼓励你考虑一下这个数据是不是全局的;很可能会把它处理成针对在一个
模块中某几个子程序的局部数据,或处理成某一个抽象数据的一部分。
10.6.4 用存取子程序来代替全局数据