主题: C++高质量编程总结
1 :为了防止重复编译一些文件,应该使用结构:
#ifndef
#define
#endif
2 :尽量在定义变量的时候初始化,这样可以防止引用没有初始化的变量引发的错误
3 :几个推荐写法
<1>对于表达式较长的for,while等语句,可以适当的去掉一些语句,以使程序显得紧凑
推荐写法:
for (i=0; i<10; i++)
不推荐写法:
for (i = 0; i < 10; i++)
推荐写法:
if ((a>=b) && (b>=c))
不推荐写法:
if ((a >= b) && ( b >= c ))
说明:很显然这样的程序不太好看
<2>if, while, for等关键字的后面应该跟着空格,这样突出关键字
推荐写法:
for (int i=0; i<10; i++)
不推荐写法:
for(int i=0; i<10; i++)
<3>函数名的后面应该紧跟着括号:
推荐写法:
void Fun(int a, int b)
不推荐写法:
void Fun (int a, int b) ;
<4>指针的推荐写法:
推荐写法:
int *x = &y ;
不推荐写法:
int* x = &y ;
<5>一些函数如果不是很容易懂,应该在前面加上注释:
例如:
/*
*函数介绍:
*输入参数:
*输出参数:
*返回值:
*/
void Function(float x, float y, float z)
{
}//end of Function
4 :注释的位置
一般放在语句的上方或者右方
5 :类中private和public的前后位置:
类中的private数据一般放在后面,因为别人不太原意看见一堆私有数据
6 :常量常用大写字母,单词之间常采用下划线来分割单词:
例如:
int MAX = 100 ;
int MAX_LENGTH = 100 ;
7 :变量的重要命令规则
<1> static变量 :int s_Number ;
<2> member变量 :int m_Number ;
<3> 如果不得已要使用全局变量,则最好在变量的名字前面加上g_表示全局变量:
例如:
int g_value = 0 ;
8 :类的数据成员前面一般加上m_这样可以防止和函数的参数重名
例如:
void setValue(int width, int length)
{
m_width = width ;
m_length = length ;
}
9 :布尔变量的注意点:
例如:
bool flag = true ;
推荐用法:
if (flag)
{
}
if(!flag)
{
}
不推荐用法:
if(flag == true) ;
if(flat == 1);
if(falg > 0) ;
不要拿着布尔变量和0和1进行比较
10:浮点数的注意点
不可以将浮点变量和任何数字进行比较,应该转换成和误差的大小进行比较:
例如:
推荐写法:
if(x >= -EPSINON || x <= EPSINON)
不推荐写法:
if(x == 0.0)
注意:对于整数可以直接进行比较
11:指针变量的比较:
推荐写法:
if(p == NULL);
if(p != NULL);
不推荐写法:
if(p == 0) ;
if(p != 0) ;
12:在循环语句中,for的使用频率最高,while其次,dowhile最少
13:在多重循环中,如果有可能,应该把次数多的循环放在内层,把次数比较少的循环放在外面,这样
可以提高程序的效率
14:for循环中的高效率的写法:
高效率写法:
if(condition)
{
for(i=0; i doSomeThing ;
}
else
{
}
15:在switch语句中,最后即使不需要default处理,最好也要加上default处理,这样的程序比较容易:
case 1:
....
default:
break ;
16:常量:
在C语言中,常量用#define来声明
在C++中,常量还可以用const来声明
17:const常量和define常量的比较:
<1>const常量有数据类型,而define定义的常量没有数据类型,编译器可以对前者进行安全检查,对后者不能
<2>define定义的常量会产生边际效应
<3>在C++中,完全用const定义常量,不再使用define定义常量
18:在C++中,常用最好使用const来声明...const来声明常量有着比宏定义更多的优点
19:类中的const常量:
在类中,用const修饰的常量只在一个对象期间是常量,对于类来说不是常量,因为对于对象不通
这个常量的值可以不同,也就是说类中const常量的作用时间是整个对象
20:注意:类中const常量的初始化只能在初始化表中进行
例如:
class Time
{
private:
const int NO ;
int hour ;
int minute ;
int second ;
public:
Time(int h, int m, int s) ;
} ;
Time::Time(int h, int m, int s):NO(2), hour(h), minute(m), second(s) {}
这样是错误的:
Time::Time(int h, int m, int s)
{
hour = h ;
minute = m ;
second = s ;
NO = 2 ; //这样是错误的!!!!
}
21:如果参数要求传递的是对象不能改变对象,则函数的参数的类型应该是:
const &类型的,这样传递的优点是提高传递的效率,省略构造对象的时间
22:避免函数有太多的参数,函数的参数控制在5个以内
23:隐含的错误:
char c ;
c = getchar() ;
if(c == EOF)
cout<< "End Of File" << endl << endl ;
错误:
getchar()返回的整型数据,他的值的范围就是ASCII码的范围:-128,127
24:这样的隐含错误:
char * fun()
{
char str[] = "Hello" ;
return str ;
}
这个函数可以说就是错误的,因为返回一个临时变量的地址
25:写return语句时的注意点
写函数return语句的时候一定要清楚返回的是值,引用,还是指针
26:如果函数的return的是一个对象,那么应该考虑效率了
例如:
return String(str1+str2) ;
说明:创建一个临时变量并且返回它
->(1)return String(str1+str2) 和
(2)String temp = str1 + str2 ;
return temp 的区别:
(1)编译器直接新创建一个临时对象,并且利用这个临时对象直接初始化外部的变量,效率
比较高
(2)第(2)句有几个过程,效率比较低:
(1)新建一个String对象
(2)对这个对象进行初始化
(3)调用对象的拷贝函数来初始化外部的对象
27:引用和指针的比较:
(1)引用不是一个变量的拷贝,也不是一个变量的指针,其实就是这个变量自己
(2)不能有NULL引用,但是可以指针可以指向NULL
(3)引用一旦初始化就不能改变它的值,但是指针是可以的
28:引用和指针该如何选择呢?
(1)引用可以作的事情,指针都可以做到
(2)因为指针可以指向内存中的任何空间,所以使用指针的时候一定非常小心
(3)在能用引用的地方应该就用引用,这样就可以避免危险
29:内存分配的三种方式:
(1)静态内存分配:
程序中的static变量和全局变量在函数编译的时候空间就已经分配好了,这样的内存叫做
静态内存
(2)栈上分配的内存:
函数中的局部变量分配的内存是在栈上的,这些空间在函数结束的时候就会自动被分配
(3)动态内存(从堆上分配)
程序员用new和delete来分配和释放的内存,这些内存的分配比较灵活,但是问题也很多
30:断言:assert的应用:
(1)程序一般分为Debug版本和Release版本,Debug版本是调试版本,是内部版本,Release版本是
发行给用户的版本
(2)assert是仅在Debug版本起作用的宏
(3)assert的作用机理:
如果assert的参数为假,那么程序就会中止
(4)assert的作用:
用于检查不该发生的情况(一般还会有提示对话,提示在什么地方发生了assert)
例如:下面的内存复制函数:
void memcpy(byte *pbTo, byte *pvForm, int size)
{
assert((pbTo != NULL) && (pvForm != NULL)) ;//使用断言
byte * pmTo = pbTo ;//这样用于防止改变pbTo
byte * pnTo = pvTo ;//同上
while(size-- > 0)
*pmTo++ = *pmTo++ ;
return pbTo ;
}
(5)断言捕捉的是非法情况,而不是错误情况
(6)在函数的入口处,检查函数参数的合法性
31:动态分配内存的注意点
一定要检查一下内存是否分配成功
32:野指针的产生:
只用free释放内存之外,但是没有给指向这个内存的指针赋值成NULL,导致这个指针变成野指针
33:在修改的时候一定要认清是常量还是变量:
例如:
char *p = "Hello" ;
(*p) = 'x' ;
这样是错误的,因为p指针指向的是个常量字符串,如果修改,则会产生错误!
34:字符串的内容复制和比较:
(1)字符串的复制不能直接使用=来进行,比较不能直接只用==来进行
(2)复制用strcpy函数来进行,比较用strcmp函数来进行
35:申请一段空间,并进行数组间的复制:
例如:
char a[] = "Hello" ;
char *p = new char[strlen(a)+1] ;//分配多一个空字节的空间(字符串的性质)
strcmp(p, a) ;
if(strcmp(p, a) == 0);
注意:字符传的空间计算的时候一定要注意最后的哪个空字节
36:C/C++是没有办法知道一个指针指向的内存容量的,除非在申请空间的时候记住它:
例如:
char * p = "Hello" ;
cout<< sizeof(p) << endl ;
结果:4
4是一个指针变量所占的字节数
37:注意:数组的名字:
(1)一般情况对于数组名字求sizeof,那么返回值将是数组的大小
(2)当数组名字用作函数从传递参数的时候,那么返回值将是指针的大小,因为在函数传递的时候
数组的名称实际上就是指针
阅读(1717) | 评论(0) | 转发(0) |