《C/C++高质量编程》笔记
来源:互联网 发布:windows 8.1怎么激活 编辑:程序博客网 时间:2024/05/29 07:36
引言:《C/C++高质量编程》这本书,很好的给出了一些编程规范,是每一个C/C++程序员都应该认真读取的一本书。几次阅读,几次忘记,今天把一些关键点记录下来,便于以后继续学习和参考。建议此书和谷歌C++编码规范一起使用,相得益彰。
【规则2-2-1】一行代码只做一件事情,如只定义一个变量,或只写一条语句。这样的代码容易阅读,并且方便于写注释。
【建议2-2-1】尽可能在定义变量的同时初始化该变量(就近原则)
【规则2-3-1】关键字之后要留空格。象const、virtual、inline、case 等关键字之后至少要留一个空格,否则无法辨析关键字。象if、for、while等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。
【规则2-3-2】函数名之后不要留空格,紧跟左括号‘(’,以与关键字区别。
【规则2-5-1】代码行最大长度宜控制在70至80个字符以内。代码行不要过长,否则眼睛看不过来,也不便于打印。
【规则2-6-1】应当将修饰符 * 和 & 紧靠变量名
例如:
char *name;
int *x, y; // 此处y不会被误解为指针
【规则3-1-6】变量的名字应当使用“名词”或者“形容词+名词”。
例如:
float value;
float oldValue;
float newValue;
【规则3-1-7】全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。
例如:
DrawBox(); // 全局函数
box->Draw(); // 类的成员函数
【建议3-1-1】尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号。
【规则3-2-1】类名和函数名用大写字母开头的单词组合而成。
例如:
class Node; // 类名
class LeafNode; // 类名
void Draw(void); // 函数名
void SetValue(int value); // 函数名
【规则3-2-2】变量和参数用小写字母开头的单词组合而成。
例如:
BOOL flag;
int drawMode;
【规则3-2-4】静态变量加前缀s_(表示static)。【规则3-2-5】如果不得已需要全局变量,则使全局变量加前缀g_(表示global)。
const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。
不能在类声明中初始化const数据成员。
const数据成员的初始化只能在类构造函数的初始化表中进行,例如
class A
{…
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的初始化表
【建议6-2-2】如果函数的返回值是一个对象,有些场合用“引用传递”替换“值传递”可以提高效率。【规则6-3-2】在函数体的“出口处”,对return语句的正确性和效率进行检查。
如果函数有返回值,那么函数的“出口处”是return语句。我们不要轻视return语句。如果return语句写得不好,函数要么出错,要么效率低下。
注意事项如下:
(1)return语句不可返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。例如
char * Func(void)
{
char str[] = “hello world”; // str的内存位于栈上
…
return str; // 将导致错误
}
(2)要搞清楚返回的究竟是“值”、“指针”还是“引用”。
(3)如果函数返回值是一个对象,要考虑return语句的效率。例如
return String(s1 + s2);
这是临时对象的语法,表示“创建一个临时对象并返回它”。不要以为它与“先创建一个局部对象temp并返回它的结果”是等价的,如
String temp(s1 + s2);
return temp;
实质不然,上述代码将发生三件事。首先,temp对象被创建,同时完成初始化;然后拷贝构造函数把temp拷贝到保存返回值的外部存储单元中;最后,temp在函数结束时被销毁(调用析构函数)。然而“创建一个临时对象并返回它”的过程是不同的,编译器直接把临时对象创建并初始化在外部存储单元中,省去了拷贝和析构的化费,提高了效率。
类似地,我们不要将
return int(x + y); // 创建一个临时变量并返回它
写成
int temp = x + y;
return temp;
由于内部数据类型如int,float,double的变量不存在构造函数与析构函数,虽然该“临时变量的语法”不会提高多少效率,但是程序更加简洁易读。
内存分配方式
内存分配方式有三种:
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。
【规则7-2-5】用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
内存耗尽怎么办?
如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。通常有三种方式处理“内存耗尽”问题。
(1)判断指针是否为NULL,如果是则马上用return语句终止本函数。
(2)判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行。(3)为new和malloc设置异常处理函数。
关键字inline必须与函数定义体放在一起才能使函数成为内联,仅将inline放在函数声明前面不起任何作用。
使用const提高函数的健壮性
const常量,const更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。用const修饰函数的参数,const只能修饰输入参数。
如果输入参数采用“指针传递”,那么加const修饰可以防止意外地改动该指针,起到保护作用。
如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const修饰。
例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A为用户自定义的数据类型。
对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。
例如函数
const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str = GetString();
如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。
例如不要把函数int GetInt(void) 写成const int GetInt(void)。
同理不要把函数A GetA(void) 写成const A GetA(void),其中A为用户自定义的数据类型。
如果返回值不是内部数据类型,将函数A GetA(void) 改写为const A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。- 《高质量C++&C编程指南》笔记
- 《高质量C++C编程指南》笔记
- 高质量C++C编程指南笔记
- 高质量C&C++编程指南---笔记
- 高质量C/C++编程笔记1
- 高质量C、C++编程指南 笔记
- 高质量 C/C++编程笔记
- 《高质量C/C++编程》笔记
- 《高质量C/C++编程指南》笔记
- 高质量C/C++编程笔记.
- 【C/C++高质量编程 笔记】
- [推荐]《C/C++高质量编程》笔记
- C/C++高质量编程笔记
- 高质量c/c++编程笔记<一>
- 高质量C/C++编程指南笔记
- 《C/C++高质量编程》笔记
- 【C】【笔记】高质量C++编程指南
- 高质量C++/C编程指南学习笔记(上)
- 2015年3月3日
- BZOJ 3527 ZJOI 2014 力 FFT
- AmazeUI中控制 li 展开于否的CSS
- onkeyup,onkeydown和onkeypress区别
- C++:函数名后加const
- 《C/C++高质量编程》笔记
- BZOJ 3829 Poi2014 FarmCraft 树形DP+贪心
- 【设计模式】单例模式
- IE与FF脚本兼容性问题
- ORACLE 存储过程基本语法
- js在IE和FF下的兼容性问题
- 正月里剃头,会死舅舅?错,仅是“思旧”的谐音而已
- 解决yum的奇怪问题,先执行以下命令
- Struts2返回JSON对象