接上文C++基础内容
1.引用
(1)定义:引用简单来说就是给变量取个别名,它和它引用的变量共用同一块内存空间。;举个例子,你在学校老师会叫你的大名,在家你父母会叫你小名,但这个名字所指向的人都是你。
(2)引用的语法格式:类型+& 变量名=引用的实体
int a = 0;
int& b = a;//b对a进行引用
(3)引用的特性:
1.引用在定义时,必须初始化,不初始化编译器会报错,因为编译器不知道你要给那个变量取个别名。
2.一个变量可以有多个引用,相当于一个变量可以有多个别名。
int a = 0;
int& b = a;
int& c = a;
int& d = a;
3.一旦引用了一个实体,再不能引用其他实体。就相当于每一个人都有一个特定的身份证号码,不能有同时有两个能表示你的身份的身份证号码。
4.引用的变量和引用的实体必须是相同类型
(4)常引用:(涉及变量权限的问题)
假设一个变量+const表示该变量只能读,不能修改了,若没加表示该变量可读可写。
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
再看看以下的代码,看看该代码有没有问题
int a = 0;
const int& b = a;
a是可读可写,b是只可读,我们来看看结果吧
没有任何错误,证明大权限转化为小权限可以,小权限转化为大权限不可以。
(5)引用的使用
可以做参数也可以做返回值
我们来看一个有意思的代码
int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(1, 2);
cout << "Add(1, 2) is :" << ret << endl;
return 0;
}
这个代码的结果是什么呢?我们来看看吧
为什么是随机值呢?这就需要我们联系计算机内存存储的知识了,我们知道函数空间的开辟是在栈帧中,当代码执行到调用Add函数时,编译器会到Add函数所在的空间执行代码,代码执行完把Add函数里面的空间被系统回收了,然后ret又是Add函数返回值的别名,然后就得去被系统回收得Add函数的空间去寻找c的空间,所以c,就会出现随机值。
那么我们该如何解决这个问题呢?不需要使用引用调用,直接使用传值调用就可以得出结果7了。
(6)引用和指针的区别
指针是开辟一块空间用来存放指针所指向的变量的空间的地址
引用只是给变量的空间起了个别名
注意:在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;在底层实现上实际是有空间的,因为引用是按指针的方式来实现的(如果需要认证,可以查一下汇编代码)
2.内联函数(以空间换取时间)
(1)定义:以inline修饰的函数为内联函数,内联函数会在别人调用它时展开自身,从而导致自身没有在栈帧中开辟空间,提高了代码的运行的效率。
使用内联函数的汇编代码图,图中显示Add内联函数并没有在栈帧上开辟空间,而是直接展开了代码。
注意:内联函数只是向编译器发出的一个请求,编译器可以拒绝该请求,将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器不会采用inline修饰。
3.auto关键字(c++11)
随着我们学习的深入,我们所写的代码也会越来越复杂,因此表达式所用到的类型也会越来越复杂,如果每次在计算表达式时,都要书写表达式的复杂的类型,我们有可能会写错,书写也非常的麻烦。因此c++11规定出一个关键字auto,auto可以自动识别表达式的类型。那么我们如何使用auto呢?
int TestAuto()
{
return 10;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;//这个代码表示输出变量b的类型
cout << typeid(c).name() << endl; //这个代码表示输出变量c的类型
cout << typeid(d).name() << endl; //这个代码表示输出变量d的类型
return 0;
}
使用auto时,需要注意以下几点:
1.使用auto必须初始化,如果不初始化,编译器无法判断该表达式是什么类型,编译器就会报错。
auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
2.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
3.auto在同一行中定义多个变量必须是相同的类型,否则会报错
4.auto不能用来判断函数形参的类型,也不能直接用来声明数组。
3.C++中的空指针
在定义一个指针时,需要给该指针初始化,在c语言中给指针初始化为空是int* a=NULL;
但在C++中如果按照C语言那种方法初始化指针,可能会出现问题。
我们可以看看这个代码
void f(int)
{
cout<<"f(int)"<<endl;
}
void f(int*)
{
cout<<"f(int*)"<<endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);//**这里本意是传NULL指针过去调用void f(int*)函数,但由于NULL表示0,需要强制转化为整形指针类型**
return 0;
}
4.总结:
到这里c++的基础知识就已经总结完了,C++基础知识对于后面的学习类和对象的内容至关重要,需要我们高度重视C++基础知识,下篇博客就是对C++的类和对象进行总结了,加油!