第一周:从C到C++
引用
概念
类型名&引用名=某变量名
某个变量的引用,等价于这个变量,相当于该变量的别名
注意事项
1.定义引用时一定要将其初始化成引用某个变量。
2.初始化后,它就一直引用该变量,不会再引用别的变量。
3.引用只能引用变量,不能引用常量与表达式
引用的使用场景
1.作为形参,能够在函数内对参数进行改变(如SWAP函数)
2.作为函数的返回值
常引用
定义引用时,前面加const关键字,即为“常引用”
特点:不能通过常引用去修改其引用的内容。
const T&和T&是不同的类型:
T&类型的引用或T类型的变量可以用来初始化const T&类型的引用。
const T&类型的常变量和const T&类型的引用则不能用来初始化T &类型的引用,除非进行强制类型转换。
const关键字
定义常量
可以定义不同类型的常量。
const int a=5;
const double b=4.0;
定义常量指针
常量指针指不可通过常量指针修改其指向的内容(并非其指向的内容修改,只是不能通过这个指针修改)
不能把常量指针赋给非常量指针,反过来可以
const int *p1;int*p2;
p1=p2;//ok
p2=p1;//error
p2=(int *)p1;//强制类型转换,ok
常量指针指向的东西倾向于不能修改,如果可以赋值给非常量指针,就可以被修改,所以这种转换不被允许。
函数参数为常量指针时,可以避免函数内部不小心改变参数指针所指地方的内容:
void MyPrintf(const char *p)
{
strcpy(p,"this");//编译出错,p应该是char然而传入的是const char无法完成转化。
printf("%s",p);//ok
}
定义常引用
见上面一节
动态内存分配
用new运算符实现动态内存分配
1.分配一个变量:
P=new T;
T是任意类型名,P是类型为T* 的指针。
动态分配出一片大小为sizeof(T)字节的内存空间,并且将该内存空间的起始地址赋值给P。
int *pn;
pn=new int;
*pn=5;
2.分配一个数组:
P=new T[N];
N为要分配的数组元素的个数,可以是整型表达式
动态分配出一片大小为N*sizeof(T)字节的空间,并将该内存空间的起始地址赋值给P。
new运算符的返回类型为T*
用delete运算符释放动态分配的内存
1.释放一个变量
用“new”动态分配的内存空间,一定要用“delete”运算符进行释放。
一片动态分配的空间不能被delete两次。
2.释放一个数组
用“delete”释放动态分配的数组,要加“[ ]”。
内联函数
函数调用是有开销的,如果函数本身只有几条语句,执行非常快,而且函数被反复执行很多次,相比之下调用函数所产生的这个开销就会显得比较大。
为了减少函数调用的开销,引入了内联函数机制。编译器处理对内联函数的调用语句时,是将整个函数的代码插入到调用语句出。
在函数定义前面加“inline”关键字,即可定义内联函数。
函数重载
一个或多个函数,名字相同,然而参数个数或参数类型不相同,这叫做函数的重载。
以下三个函数是重载关系:
int Max(double f1,double f2){ }
int Max(int n1,int n2){ }
int Max(int n1,int n2,int n3{ }
编译器根据调用语句的中的实参的个数和类型判断应该调用哪个函数(不是返回类型)。
如果编译器发现函数调用时具有二义性,那么会报错。
函数缺省参数
C++中,定义函数的时候可以让最右边的连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写参数,参数就是缺省值。
void func(int x1,int x2=2,int x3=3){ }
func(10);//等效于func(10,2,3)
func(10,8);//等效于func(10,8,3)
func(10,,8);//不行,只能最右边的连续若干个参数缺省
函数参数可缺省的目的在于提高程序的可扩充性。