编写高质量代码——“零星”总结

不要让main函数返回void

//在C++中绝对没有出现过 void main(){  }这种函数定义,在C语言中也是。


//两种 main 的定义方式:int main( void );
//                     int main( int argc, char** argv )

//第一版的C语言中仅仅有 int 一种数据类型。为了兼容

须要,不明白标明返回值的。默觉得 int

//在main函数中,return 语句的作用在于离开main函数(析构掉全部具有动态生存时间的对象),并将其返回值作为參数来调用 exit 函数。假设运行到main结束处时,没有遇到return语句,编译器会隐式加上return 0。该规则只对 main 函数适用。

============================================

区分0的4种面孔

//整型0、空指针NULL、字符串结束标志 '\0'、逻辑FALSE/false
//'\0' 是一个字符,只占 8 位,二进制为 0000 0000。由于字符类型中没有与 0000 0000 相应的字符,故在C/C++中,'\0' (转义字符)被作为字符串结束标志适用,具有唯一性,与 '0' 是有差别的。


//FALSE是C的宏定义,是 int 类型;false是C++的keyword。是 bool 类型,仅仅占一个字节。

============================================

避免那些由运算符引发的混乱

//if(0 = value)      常数 0  不能作为左值来使用

============================================

对表达式计算顺序不要想当然

//操作符优先级,不要吝啬使用括号

//函数參数(要保证凡是在參数表中出现过一次以上的变量,在传递时不改变其值,即使如此也并不是万无一失)和操作数的评估求值顺序由编译器决定,小心陷阱,让表达式不要依赖计算顺序。

============================================

小心宏#define使用中的陷阱

//使用完备的括号、不同意參数发生变化、用大括号{}将宏所定义的多条表达式括起来

============================================

不要忘记指针变量的初始化

============================================

明晰逗号分隔表达式的奇怪之处

//在使用逗号分隔表达式时,C++会确保每一个表达式都被运行,整个表达式的值为最右边表达式的结果。

============================================

时刻提防内存溢出

//C语言中的 字符串库 没有採用对应的内存安全保护措施,使用时要特别小心。

如:strcpy、strcat等函数无缓冲区大小检查。

============================================

拒绝晦涩难懂的函数指针
//typedef void (*pfv)( );
//typedef void (*pFun_taking_pfv)( pfv )

//pFun_taking_pfv p[10];   /* 等同于void (*p[10]) (void (*)( )) */

============================================

防止反复包括头文件

//编译器在每次编译时都须要打开文件才干判定是否有反复定义。因此在编译大型项目时。ifndef 会使编译时间相对较长。

============================================

优化结构体中元素的布局
//字节对齐:现代计算机中内存空间都是依照 字节 来划分的,从理论上来讲,对变量的訪问能够从不论什么地址開始;但在实际情况中。为了提升存取效率,各类型数据依照一定的规则在空间上排列,这使得某些特定类型的数据仅仅能从某些特定地址開始存取。以空间换取时间。

//#pragma pack(n)   /* n 为字节对齐数,其取值为1、2、4、8、16。默认是 8 */

============================================

将强制转型减到最少
//在标C 中,强制转型可能导致内存扩张与截断。由于在标C中。不论什么非 void 类型的指针都能够和 void 类型的指针相互指派,即能够通过 void 类型指针作为中介,实现不同类型的指针间接相互转换:
//double PI = 3.14;
//double *pd = Π
//void *temp = pd;

//int *pi = temp;   //转换成功

============================================

优先使用前缀操作符
//差别非常细微,主要体如今执行效率上。前缀操作省去了暂时对象的构造,效率上优于后缀操作(用户自己定义类型,值得注意)。
//成员函数形式的重载:
//<Type> ClassName :: operator ++(  );  //前缀
//<Type> ClassName :: operator ++( int ); //后缀


//非成员函数形式的重载:

//<Type> ClassName :: operator ++( ClassName & ); //前缀

//<Type> ClassName :: operator ++( ClassName &。 int ); //后缀

============================================

掌握变量定义的位置与时机
//C++规则同意在函数的不论什么位置定义变量,当程序运行到变量定义的位置,就会调用对应的构造构函数。
//当程序控制点超出变量的作用域时,就会调用对应的析构函数,完毕对该变量的清理。

// 对象的构造和析构不可避免地会带来一定的开销,故应把握好变量定义的时机:尽量晚定义。尽量缩小作用域。

============================================

小心typedef使用中的陷阱
//typedef  int*  PTR_INT1;  //对类型别名具有一定的封装性 | 同一时候声明多个指针类型的对象
//PTR_INT1  pNum1, pNum2;   // int *pNum1, *pNum2;

//注意:typedef 在语法上是一个存储类的keyword(auto、extern、mutable、static、register等)。并不会真正影响对象的存储特性

//typedef static int a; //指定了一个以上的存储类型

============================================

尽量不要使用可变參数
//C风格的可变參数的缺点:
(1)缺乏类型检查,类型安全性无从谈起。“省略号...的本质是告诉编译器‘关闭全部检查,并启动reintepret_cast’”。强制将某个类型对象的内存表示又一次解释成第二种对象类型,违反了“类型安全性”。
(2)由于禁用了语言类型检查功能。全部在调用时必须通过其它方式告诉函数所传递參数的类型。以及參数个数。
(3)不支持自己定义数据类型。



//C++多态性:实现了可变參数的安全可靠的有效途径。


============================================

慎用goto
//使用的情形:程序在一组嵌套循环中出现错误。无路可走时的跳转处理。

posted on 2017-04-23 10:56  ljbguanli  阅读(199)  评论(0编辑  收藏  举报