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

不要让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++的关键字,是 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 在语法上是一个存储类的关键字(auto、extern、mutable、static、register等),并不会真正影响对象的存储特性

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

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

尽量不要使用可变参数

//C风格的可变参数的缺点:

(1)缺乏类型检查,类型安全性无从谈起。“省略号...的本质是告诉编译器‘关闭所有检查,并启动reintepret_cast’”,强制将某个类型对象的内存表示重新解释成另外一种对象类型,违反了“类型安全性”。

(2)因为禁用了语言类型检查功能,所有在调用时必须通过其他方式告诉函数所传递参数的类型,以及参数个数。

(3)不支持自定义数据类型。

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

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

慎用goto

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

编写高质量代码——“零星”总结,布布扣,bubuko.com

时间: 2024-10-23 09:55:09

编写高质量代码——“零星”总结的相关文章

编写高质量代码——“零星”总结(续3)

明白在C++中如何使用C C++中使用C的程序库,实现C++和C的混合编程:extern "C" { /* code */ }一定要加在C++的代码文件中才能起作用. //C编译器编译函数时不带函数的类型信息,只包含函数符号名字:而C++编译器为了实现函数重载,在编译时会带上函数的类型信息.extern "C"的作用:告诉C++链接器寻找调用函数的符号时,采用C的方式. =================================== 使用memcpy()系列

编写高质量代码——“零星”总结(续2)

newdelete与new[]delete[]必须配对使用 //注意,由于内置数据类型没有构造.析构函数,所以针对内置数据类型时,释放和内存使用delete或delete[]的效果是一样的. 例如: int *pArray = new int[10]; ...//processing code delete pArray;  //等同于delete[] pArray; 虽然针对内置类型,delete和delete[]都能正确地释放所申请的内存空间,但是如果申请的是一个数组,建议还是使用delet

每周一书-编写高质量代码:改善C程序代码的125个建议

首先说明,本周活动有效时间为2016年8月28日到2016年9月4日.本周为大家送出的书是由机械工业出版社出版,马伟编著的<编写高质量代码:改善C程序代码的125个建议>. 编辑推荐 10余年开发经验的资深C语言专家全面从C语法和C11标准两大方面深入探讨编写高质量C代码的技巧.禁忌和实践 C语言因为既具有高级语言特性,又具有汇编语言特性,所以它是近二十几年来使用较为广泛.生命力较强的编程语言.无论是操作系统.嵌入式系统.普通应用软件,还是移动智能设备开发,它都能够很好地胜任,是公认的强大的语

代码质量优先——《编写高质量代码:改善c程序代码的125个建议》

高质量的代码不但可以促进团队合作.减少bug处理.降低维护成本,对程序员自身的成长也是至关重要的.很难想象一个参考<如何编写无法维护的代码>写代码的程序员技术成长的上限有多么低.为了写出高质量的代码,我们需要听取过来人的改善代码质量的经验,<编写高质量代码:改善c程序代码的125个建议>就是一本能让人写出高质量代码的好书. 本书的第三章<程序控制语句应该保持简洁高效>首先用简练的语言介绍了流程控制结构的概念,然后提供了对if.else.for.do-while.swit

[ 转 ]编写高质量代码:改善Java程序的151个建议

记得3年前刚到公司,同桌同事见我无事可做就借我看<编写高质量代码:改善Java程序的151个建议>这本书,当时看了几页没上心就没研究了.到上个月在公司偶然看到,于是乎又找来看看,我的天,真是非常多的干货,对于我这种静不下心的人真是帮助莫大呀. 看完整本书,也记了不少笔记,我就分享一部分个人觉得有意义的内容,也为了方便以后自己温习. --警惕自增陷阱 i++表示先赋值后自增,而++i表示先自增后赋值.下面的代码返回结果为0,因为lastAdd++有返回值,而返回值是自增前的值(在自增前变量的原始

编写高质量代码改善C#程序的157个建议——建议45:为泛型类型参数指定逆变

建议45:为泛型类型参数指定逆变 逆变是指方法的参数可以是委托或者泛型接口的参数类型的基类.FCL4.0中支持逆变的常用委托有: Func<int T,out TResult> Predicate<in T> 常用委托有: IComparer<in T> 下面例子演示了泛型类型参数指定逆变所带来的好处: class Program { static void Main() { Programmer p = new Programmer { Name = "Mi

编写高质量代码改善C#程序的157个建议——建议27:在查询中使用Lambda表达式

建议27:在查询中使用Lambda表达式 LINQ实际上是基于扩展方法和Lambda表达式的.任何LINQ查询都能通过扩展方法的方式来代替. var personWithCompanyList = from person in personList select new { PersonName = person.Name, CompanyName = person.CompanyID==0?"Micro":"Sun" }; foreach (var item in

编写高质量代码改善C#程序的157个建议——建议26:使用匿名类型存储LINQ查询结果

建议26:使用匿名类型存储LINQ查询结果 从.NET3.0开始,C#开始支持一个新特性:匿名类型.匿名类型有var.赋值运算符和一个非空初始值(或以new开头的初始化项)组成.匿名类型有如下基本特性: 即支持简单类型也指出复杂类型.简单类型必须是一个非空初始值,复杂类型则是一个以new开头的初始化项. 匿名类型的属性是只读的,没有属性设置器,它一旦被初始化就不可更改. 如果两个匿名类型的属性值相同,那么就认为这两个匿名类型相等. 匿名类型可以再循环中用作初始化器. 匿名类型支持智能感知. 匿名

编写高质量代码改善C#程序的157个建议——建议20:使用泛型集合代替非泛型集合

建议20:使用泛型集合代替非泛型集合 在建议1中我们知道,如果要让代码高效运行,应该尽量避免装箱和拆箱,以及尽量减少转型.很遗憾,在微软提供给我们的第一代集合类型中没有做到这一点,下面我们看ArrayList这个类的使用情况: ArrayList al=new ArrayList(); al.Add(0); al.Add(1); al.Add("mike"); foreach (var item in al) { Console.WriteLine(item); } 上面这段代码充分演