C++编程规范 编程风格 学习 (4) -- 总是初始化变量

来源:互联网 发布:淘宝网65平开窗传动器 编辑:程序博客网 时间:2024/06/03 01:41

总是初始化变量


    未初始化的变量是C和C++程序中错误的常见来源。养成在使用内存之前先清除的习惯,可以避免这种错误,在定义变量的时候就将其初始化。

    关于未初始化变量,有一个常见的误解:它们会使程序崩溃,因此通过简单的测试就能很快发现分布在各处的那些为数不多的未初始化变量。但事实恰恰相反,如果内存局部碰巧满足了程序需求,带有未初始化变量的程序能够毫无问题地运行数年。在此之后,如果从不同环境中调用,或者重新编译,或者程序的另一个部分进行了修改,都可能导致各种故障发生,轻则出现难以琢磨的行为,重则发生间歇性的崩溃。

一般来说,分离声明和定义不是一个好的做法。
int x;
x = 123;
string szName;
szName = "Zhang";
在这些变量被赋值之前,它们具有不确定的值,字符串可以通过构造函数而正确的初始化,然后再由随后的赋值操作立即被覆盖。
最好的做法是,在声明的时候进行显示的初始化。
int x = 123;
string szName("Zhang");

bool f( const char *s ){    size_t length;    if( !s ) return false;    length = strlen( s );    char *buffer = (char *)malloc( length+1 );    // . . .}
这里的length不仅没有初始化,而从语义上来看,length应该是一个常量,所以更好地做法是将length声明为const并且直接赋值:
bool f( const char *s ){    if( !s ) return false;    const size_t length = strlen( s );    char *buffer = (char *)malloc( length+1 );    // . . .}
这段代码,看起还行啊,有初始化
void process( const char *id ){    Name *function = lookupFunction( id );   if( function )    {       // . . .   }}
但是问题还没暴露出来,这段代码在后期维护的时候有可能就会有问题。
有时候处于“懒”,“省事”,经常会重用某个局部变量来达到目的,因为这样用起来容易。
void process( const char *id ) {    Name *function = lookupFunction( id );if( function ){// process function . . .}else if( function = lookupArgument( id ) ) {// process argument . . .}   // . . .   if( function ){// postprocess function . . .}}
后面维护给function又在if里面加了重新定义,而function的名称和作用域没有得到良好的限制,有可能再越多的维护中出现麻烦,而有效的限制变量名称的范围作用域,一方面可以防止重复使用它,也便于维护,使得代码更加合理清晰。
void process( const char *id ) {    if( Name *function = lookupFunction( id ) )    {       // . . .       postprocess( function );   }   else if( Name *argument = lookupArgument( id ) )   {       // . . .   }}

使用默认初始值或三目运算 ?: 用于减少数据流和控制流的混合。
//不可取的:没有初始化变量int speedupFactor;if(condition){speedupFactor = 2;}else{speedupFactor = -1;}//较好的:初始化了变量int speedupFactor = -1;if(condition){speedupFactor = 2;}else{speedupFactor = -1;}//较好的:初始化了变量int speedupFactor = condition ? 2 : -1;

可用函数来代替复杂的计算流。有时候计算值的最好方式是将计算封装到一个函数中
int speedupFactor = ComputerSpeedupFactor();

初始化数组,正确的初始化并不总是意味着要真的对所有数据进行操作。
例如,假设一个API要求使用大小为MAX_PATH的固定char数组。
如果能肯定数组重视被当做空字符结束的C语言字符串处理的话,这种立即赋值的方式就已经很好了:
char path[MAX_PATH];
path[0] = '\0';
下面这种更安全的初始化则用0来填充了数组里的全部字符:
char path[MAX_PATH] = {‘\0’};
一般而言,两种方法都可以,但从安全性来考虑,安全是优于效率的。


原创粉丝点击