C++语言基础(8)-引用
(重要)使用引用的一些注意点:
1.引用不能绑定临时数据,也不能绑定任何无法获取内存地址的常量,表达式,或值,常引用除外。
第一种写法:(错误)
int func_int(){
int n = ;
return n;
}
int main(){
int m = , n = ;
int &r1 = m + n;
int &r2 = m + ;
int &r3 = * ;
int &r4 = ;
int &r5 = func_int();
return ;
}
第二种写法:
bool isOdd(int &n){
if(n/ == ){
return false;
}else{
return true;
}
}
int main(){
int a = ;
isOdd(a); //正确
isOdd(a + ); //错误
isOdd(); //错误
isOdd( + ); //错误
return ;
}
第三种写法(正确)
int func_int(){
int n = ;
return n;
}
int main(){
int m = , n = ;
const int &r1 = m + n;
const int &r2 = m + ;
const int &r3 = * ;
const int &r4 = ;
const int &r5 = func_int();
return ;
}
第四种写法:(正确)
bool isOdd(const int &n){ //改为常引用
if(n/ == ){
return false;
}else{
return true;
}
}
int a = ;
isOdd(a); //正确
isOdd(a + ); //正确
isOdd(); //正确
isOdd( + ); //正确
为什么加了const就可以?这是因为将常引用绑定到临时数据时,编译器采取了一种妥协机制:编译器会为临时数据创建一个新的、无名的临时变量,并将临时数据放入该临时变量中,然后再将引用绑定到该临时变量。注意,临时变量也是变量,所有的变量都会被分配内存。
2.const修饰引用时三种写法的区别:
第一种写法(错误)
int a = ;
int & const r = a;
第二种写法(正确)
int a = ;
int const &r = a;
第三种写法(正确)
int a = ;
const int &r = a;
上述三种写法中,第一种写法是严重错误的。因为引用在定义时就必须初始化,并且以后也要从一而终,不能再指向其它数据,这也就意味着r本来就不能改变指向,加上const纯属多此一举。
第二种写法和第三种写法本质上是一样的,在定义引用时加上const限制,目的都是不希望通过引用来修改原始数据的值。
一.引用的基本用法
#include <iostream>
using namespace std; int main(){
int a = ;
int &b = a;
cout<<a<<", "<<b<<endl;
cout<<&a<<", "<<&b<<endl; return ;
}
运行结果:
99, 99
0x28ff44, 0x28ff44
如果不希望通过引用修改原始数据的值,可以在定义时添加const限制:
const int &b = a; // 或
int const &b = a;
注意:引用在定义时需要添加&,在使用时不能添加&,使用时添加&表示取地址
二.引用作为函数参数
#include <iostream>
using namespace std; void swap3(int &a, int &b); int main(){
int num1, num2; cout<<"Input two integers: ";
cin>>num1>>num2;
swap3(num1, num2);
cout<<num1<<" "<<num2<<endl; return ;
} void swap3(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
运行结果:
Input two integers: 12 34
12 34
Input two integers: 88 99
99 88
Input two integers: 100 200
200 100
三.引用作为函数返回值
引用除了可以作为函数形参,还可以作为函数返回值,请看下面的例子:
#include <iostream>
using namespace std;
int &plus10(int &n){
n = n + ;
return n;
}
int main(){
int num1 = ;
int num2 = plus10(num1);
cout<<num1<<" "<<num2<<endl;
return ;
}
运行结果:
20 20
注意:在将引用作为函数返回值时应该注意一个小问题,就是不能返回局部数据(例如局部变量、局部对象、局部数组等)的引用,因为当函数调用完成后局部数据就会被销毁,有可能在下次使用时数据就不存在了,C++ 编译器检测到该行为时也会给出警告。
因此像下面的写法是不正确的:
#include <iostream>
using namespace std;
int &plus10(int &n){
int m = n + ;
return m; //返回局部数据的引用
}
int main(){
int num1 = ;
int num2 = plus10(num1);
cout<<num2<<endl;
int &num3 = plus10(num1);
int &num4 = plus10(num3);
cout<<num3<<" "<<num4<<endl;
return ;
}
不能将局部变量m返回!因为函数是在栈上运行的,并且运行结束后会放弃对所有局部数据的管理权,后面的函数调用会覆盖前面函数的局部数据。本例中,第二次调用 plus10() 会覆盖第一次调用 plus10() 所产生的局部数据,第三次调用 plus10() 会覆盖第二次调用 plus10() 所产生的局部数据。
C++语言基础(8)-引用的更多相关文章
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(上)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 一.SQL Server体系结构 1.1 数据库 ...
- C#语言基础
第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...
- C语言基础回顾
第一章 C语言基础 1. C语言编译过程 预处理:宏替换.条件编译.头文件包含.特殊符号 编译.优化:翻译并优化成等价的中间代码表示或汇编代码 汇编:生成目标文件,及与源程序等效的目标的机器语言代码 ...
- 黑马程序员_ C语言基础(二)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 概览 今天基础知识分为以下几点内容(注意:循环.条件语句在此不再赘述): 1.Hello W ...
- 【GoLang】GO语言系列--002.GO语言基础
002.GO语言基础 1 参考资料 1.1 http://www.cnblogs.com/vimsk/archive/2012/11/03/2736179.html 1.2 https://githu ...
- Java学习总结(二)----Java语言基础
1. Java语言基础 2.1 关键字 定义:被java语言赋予特殊含义的单词 特点:关键字中的字母都为小写 用于定义数据类型的关键字 class,interface,byte,short,i ...
- php面试题之三——PHP语言基础(基础部分)
三.PHP语言基础 1. strlen( )与 mb_strlen( )的作用分别是什么(新浪网技术部) strlen和mb_strlen都是用于获取字符串长度. strlen只针对单字节编码字符,也 ...
- Object Pascal 语言基础
Delphi 是以Object Pascal 语言为基础的可视化开发工具,所以要学好Delphi,首先要掌握的就是Object Pascal 语言.Object Pascal语言是Pascal之父在1 ...
随机推荐
- [BZOJ1143][CTSC2008]祭祀river(Dilworth定理+二分图匹配)
题意:给你一张n个点的DAG,最大化选择的点数,是点之间两两不可达. 要从Dilworth定理说起. Dilworth定理是定义在偏序集上的,也可以从图论的角度解释.偏序集中两个元素能比较大小,则在图 ...
- 【博弈论】【SG函数】hdu1848 Fibonacci again and again
某个状态的SG函数被定义为 除该状态能一步转移到的状态的SG值以外的最小非负整数. 有如下性质:从SG值为x的状态出发,可以转移到SG值为0,1,...,x-1的状态. 不论SG值增加与否,我们都可以 ...
- 【二分图】【最大匹配】【匈牙利算法】CODEVS 2776 寻找代表元
裸的匈牙利,存模板. #include<cstdio> #include<vector> #include<cstring> using namespace std ...
- iOS开发——异常:[__NSCFNumber length]: unrecognized selector sent to instance
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumbe ...
- MySQL查询时区分大小写(转)
说明:在MySQL查询时要区分大小写会涉及到两个概念character set和collation,这两个概念在表设计时或者在查询时都可以指定的,详细参考:http://www.cnblogs.com ...
- iOS面试_1.浅析内存管理
为了开学的面试,就在博客里总结一下面试会问到的问题,今天就来谈谈内存管理,看到一篇文章非常不错,http://vinceyuan.cnblogs.com/,深入浅出,推荐大家去看看! Objectiv ...
- ios(iphone/ipad)一个简单的用代码判断当前设备的方法
直接NSLog(@"current_device:%@",[UIDevice currentDevice].model); 即可看出它输出的是当前设备,所以根据这个字符串可简单的判 ...
- 怎样用bat批量重命名文件夹和文件
很早以前本人写过重命名文件夹的文章,发现其中稍有不完善的地方,其主要功能在文件夹名前统一加上字符,或者在文件夹名后统一加上字符,有网友反应功能太单一.今天我又仔细研究了一下bat批处理代码,分别能完全 ...
- [原创]用逻辑嗅探破解接触式IC卡口令
最近两周对接触型IC卡很感兴趣,就动手实践了一下,最终实现的效果是通过破解IC卡口令实现对数据修改,然后就可以随意洗衣服喽~IC卡从数据传递方式上划分为接触型和非接触型两种.接触型的卡片表面有金属贴片 ...
- 爪哇国新游记之二十八----从url指定的地址下载文件到本地
package download; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; ...