序列点与未定义行为
C/C++标准规定,两个序列点之间,程序执行的顺序可以是任意的。
C++2003标准中定义的序列点(详细说明请参考标准)
完整声明之后
完整表达式之后
进入函数时与退出函数时
- || && ?: , 四个操作符的第一个操作数之后(?:为条件运算符)
关于const
const 与 define
const 优于define 来定义常量的两点
- 类型安全检查(编译器可以对const常量进行类型安全检查)
- 调试工具支持(调试工具可以对const常量进行调试)
const 与 指针
- const int * a = &b;
- int const * a = &b;
若const 位于 * 左侧,则const用来修饰指针所指向的变量,不能通过*a = value 的方式改变指针a所指向的内容,但指针a可以改变其指向,a = &c。 - int * const a = &b;
若const 位于 * 右侧,则const用来修饰指针本身,即指针本身是常量,不能改变其指向,如a++就是非法的,声明的同时必须进行初始化。
const in C 与 const in C++
- C中的const是运行期的常量,所以编译时const int bufsize = 100; char buf[bufsize];将会报错。应该只声明const int bufsize;指明在别的地方有内存分配,C默认const是外部连接的。
- C++中的const是编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中。const默认使用内部连接,所以只声明const int bufsize会报错,可以用extern把内部连接改成外部链接:extern const int bufsize;
说明:
- 内连接:编译器只对正被编译的文件创建存储空间,别的文件可以使用相同的表示符或全局变量.C/C++中内连接使用static关键字指定.
- 外连接:所有被编译过的文件创建一片单独存储空间.一旦空间被创建,连接器必须解决对这片存储空间的引用.全局变量和函数使用外部连接.通过extern关键字声明,可以从其他文件访问相应的变量和函数.
const成员函数与const成员变量
- 一个成员函数声明为const可以保证这个成员函数不修改数据成员,但是,如果数据成员是指针,则const成员函数并不能保证不修改指针指向的对象,编译器不会把这种修改检测为错误。
- 只有被声明为const的成员函数才能被一个const类对象调用。
- const成员函数可以被具有相同参数列表的非const成员函数重载,在这种情况下,类对象的常量性决定调用哪个函数。
- 用mutable修饰成员变量名后,在const成员函数中就可以修改类的成员变量了。
关于指针
指针与引用的区别
- 非空区别:在任何情况下都不能使用指向空值的引用。
- 合法性区别:指针应该总是被测试,防止其为空。
- 可修改区别:指针可以被重新赋值以指向另一个不同的对象。但是引用总是指向在初始化时被指定的对象(其内容可变)。
- 应用区别:如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么应该使用引用。
函数指针与指针函数
- 函数指针声明时要有返回值和参数。
- 指针函数为返回指针的函数。
int (*(*F)(int,int))(int);//返回值为int,参数为int的函数指针内嵌一个返回值为指针,参数为(int,int)的函数指针。
double (*f[10])();//f是一个有10个元素的数组,元素都是没有参数,返回值为double的函数指针
指针数组与数组指针
- 指针数组即元素都为指针的数组
- 数组指针为指向数组的指针
int (*ptr) [];//指向整型数组的指针。
int *ptr[];int *(ptr[]);//元素为整型指针的数组
迷途指针
迷途指针也叫悬浮指针,失控指针,是当对一个指针进行delete操作(释放其指向的内存)后没有把它设置为空而产生的。
在编程时要务必记得delete指针之后要将指针赋为空(0或NULL),再次使用它时必须重新让它指向一个新地址。
安全指针
安全指针用于函数过早的return或者是在函数体内部抛出异常而没有delete在函数内部动态分配的对象,造成内存泄露的情况。
auto_ptr可被用来安全的包容指针使其在析构时自动删除此指针。
使用方法:
std:auto_ptr <Object> ptr (new Object);//Object为指针类型,ptr为指针名
std:auto_ptr <Object> source(){return new Object;}
注意:把auto_ptr放入container(如vector)中是不安全的。当auto_ptr被拷贝时,原来的那一份会被删除。
this指针
- 本质是一个函数参数,只是编译器隐藏起形式的,语法层面上的参数。
this指针只能在成员函数中使用,全局函数,静态函数都不能使用this。
实际上,成员函数默认第一个参数为T* const this。 - this在成员函数的开始前构造,在成员函数的结束后清除。
编译器通常会对this指针做一些优化,因此this指针的传递效率比较高,如VC通常是通过ecx寄存器传递this指针的。 - this指针并不占用对象空间。
它跟对象之间没有包含关系,只是当前调用函数的对象被它指向而已。
所有成员函数的参数,不管是不是隐含,都不会占用对象空间,只是占用参数传递时的栈空间,或者直接占用一个寄存器。 - this指针会因编译器的不同而有不同的放置位置,可能是堆、栈、也可能是寄存器。