c++ primer plus阅读笔记6---内联函数引用变量
2017-08-13 21:23
453 查看
1.内联函数
普通函数的调用过程中,在汇编层次看,首先将函数的返回地址压栈,然后call函数,跳转到函数的代码块去执行,完了之后从栈里弹出来返回地址。
内联函数不需要跳转到函数的代码块。在编译时,编译器就已经将函数代码和其他代码块“内联起来了,也就是编译器将使用相应的函数代码替换函数调用。”这样程序就无需跳转到另一个位置执行代码再跳回来,但是缺点是占用更多内存。
2.引用变量
引用变量在生命的时候必须将其初始化,主要作用是给函数传参。
等价于指针常量(只能指向一块内存,指向位置不能改变);
如果想用引用,又不想改变传递进去的参数的值,应该用常量引用,例如:
引用传递的限制:
返回引用:
我们来看一个有意思的代码:
指针也可以达到以上的效果,代码应该这么写:
如果要返回引用,但是同时又不希望上述可以赋值的情况出现,可以这么做:
返回值是const,不可以修改,然后下边的这种赋值就是非法的
将引用用于对象:
来对比三个函数:
普通函数的调用过程中,在汇编层次看,首先将函数的返回地址压栈,然后call函数,跳转到函数的代码块去执行,完了之后从栈里弹出来返回地址。
内联函数不需要跳转到函数的代码块。在编译时,编译器就已经将函数代码和其他代码块“内联起来了,也就是编译器将使用相应的函数代码替换函数调用。”这样程序就无需跳转到另一个位置执行代码再跳回来,但是缺点是占用更多内存。
2.引用变量
引用变量在生命的时候必须将其初始化,主要作用是给函数传参。
int &rodents=rats; 实际上下述代码的伪装表示: int *const pr=&rats;
等价于指针常量(只能指向一块内存,指向位置不能改变);
如果想用引用,又不想改变传递进去的参数的值,应该用常量引用,例如:
double refcube(const double &ra);//其实此时最好用值传递,当数据结构比较大(结构,类)时,使用引用传递很有必要
引用传递的限制:
//定义函数: double refcube(int &x); 如果按照以下方式传递参数将是非法的: refcube(a+3.0);//非法,因为x只是个别名,不能这样赋值:x+3.0=5.0
返回引用:
int cube(int &a) //返回不是引用 { return a*=a*a; //用a保存其立方值 } //如果此时调用: double sqrt3(cube(a)); //则传递sqrt3的参数是传递的值,如果返回是引用,如下: int cube(int &a) //返回不是引用 { return a*=a*a; //用a保存其立方值 4000 } //则sqrt3的参数是引用,能直接将a一直传递到sqrt函数,这在传递大对象的时候很实用 //返回引用应该注意:不能返回函数返回以后不存在的内存位置,比如: int & function(int a) { int b=a; //b分配在栈上,function函数返回后,b将不复存在 return b; } //返回引用还可以这么用: int &function(int a,int b); function(3,4)=5;//因为function返回的是一个int的引用
我们来看一个有意思的代码:
int &function(int &a,int b) { a+=b; return a; } int main() { int a=5; int b=6; cout<<(function(a,b)=7)<<endl;//输出7,因为function函数返回的是一块内存的引用,然后将7赋值给这块内存 cout<<function(a,b)<<endl;//输出13,上一条语句已经将a指向的内存赋值为7了,参数传递相当于function(7,6) }
指针也可以达到以上的效果,代码应该这么写:
int *function(int *a,int b) { *a+=b; return a; } int main() { int a=5; int b=6; cout<<*function(&a,b)<<endl; cout<<(*(function(&a,b))=7)<<endl; cout<<*function(&a,b)<<endl; }
如果要返回引用,但是同时又不希望上述可以赋值的情况出现,可以这么做:
const int &function(int &a,int b) { a+=b; return a; }
返回值是const,不可以修改,然后下边的这种赋值就是非法的
function(a,b)=5;//非法
将引用用于对象:
来对比三个函数:
string version_1(const string &s1,const string &s2) { string temp=s2+s1+s2; return temp; //temp是version_1函数定义的局部变量,函数返回后temp会被回收,在main函数中会将temp复制到一个名称为result的内存单元 } string &version_2(string &s1,const string &s2) { s1=s2+s1+s2; return s2;//返回引用,没有问题,但是副作用是改变了输入的值(s1内存的内容) } string &version_3(string &s1,const string &s2) { string temp=s2+s1+s2; return temp;//temp是局部变量,函数退出后会被回收,这里返回的是引用,主函数中试图操作一个已经被释放的内存块,会导致程序崩溃(segment fault) }
相关文章推荐
- c++ primer plus阅读笔记13---虚函数 为什么要虚析构函数?
- c++primer plus阅读笔记(五)
- c++ primer plus阅读笔记11---深拷贝与浅拷贝
- c++primer plus阅读笔记(六)
- C++primer plus阅读笔记第四章
- c++ primer plus阅读笔记14---虚基类
- c++ primer plus阅读笔记10---定位new using namespace
- c++ primer plus阅读笔记(三)
- c++primer plus阅读笔记(七)
- [C++ Primer Plus]学习笔记--C++内联函数
- c++primer plus阅读笔记(十)
- c++ primer plus阅读笔记8---decltype
- c++ primer plus阅读笔记3---指针问题
- c++ primer plus阅读笔记4---struct
- c++ primer plus阅读笔记2---结构体共用体枚举
- c++ primer plus阅读笔记12---手动调用析构函数
- c++ primer plus阅读笔记7---模板特化
- C++ Primer Plus阅读笔记
- C++ Primer plus 学习笔记之第七章(2)函数指针
- C++ Primer plus第6版第9章学习笔记