引用和指针
来源:互联网 发布:千牛与淘宝什么区别 编辑:程序博客网 时间:2024/06/07 05:53
引用(reference)是c++对c语言的重要扩充。引用就是某一已存在变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:类型标识符 &引用名=目标变量名;
假若有一变量a,想给它起一别名,可以这样写:
int a; //定义a是整形变量int &b = a; //声明b是a的引用以上语句声明了b是a的引用,即b是的别名,经过这样声明后,a或b作用相同,代表同一变量。
注意:
const int (&ref)[3] ={2,3,5}; //gcc编译的时候加上选项 -std=c++0x ref[0] = 35; //错误
void swapint( int*a, int*b){ int temp; temp = *a; *a = *b; *b = temp;}
void swapint( int &a, int &b){ int temp; temp = a; a = b; b = temp;}
const maxCard=100;Class Set{ int elems[maxCard];//集合中的元素,maxCard表示集合中元素个数的最大值。 int card;//集合中元素的个数。public: Set(){card=0;}//构造函数 friend Setoperator *(Set,Set);//重载运算符号*,用于计算集合的交集用对象作为传值参数 //friendSetoperator*(Set&,Set&)重载运算符号*,用于计算集合的交集用对象的引用作为传值参数...}
void Test{ int a ; const int &ra=a; ra=1; //错误,const修饰不可改 a=1; //正确}
string foo( ); void bar(string & s);那么下面的表达式将是非法的:bar(foo( )); bar("hello world");//原因在于foo( )和"hello world"串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。引用型参数应该在能被定义为const的情况下,尽量定义为const 。
#include <iostream>using namespace std;int& fun(int& a){ a++; return a;} //把a返回引用函数,也就是说这个fun()就是a的别名int main(){ int b =10; fun(b); //同理,fun(b)就是b自增后的b的别名 cout << b <<endl; return 0;}
【例】:
void Test{ const int a = 10; int &b = a; //错误。如果引用成功,可通过a修改成功,而原题是const修饰b,是不可修改的。 const int &b = a; // 正确 const int &c = 10; //正确,表示10不可修改}【例】:
void Test{ double a = 10.34; const int &b = a; //正确, a = 23.13;} // b = 12; //如果b是a得引用(两者类型相同),则两者使用同一空间,但事实上b并不是a得引用,因为两者有不同的空间,借助一段未命名空间过度,临时变量有常性,所以要加上const修饰。
【例】:数组引用
void Test{ int a[10]; int (&ra) [10] = a; int (&ra) [9] = a; // 错误,两者类型相同,不可引用 a [0] = 10; ra[1] = 20;}
FunTest(&a){ int a = 10; return a;}保证返回值生命周期比函数生命周期长
int & FunTest(){ int ret = 10; return ret;}int main(){ int &r = FunTest(); printf("%d\n", r); printf("%d\n", r);} // 10 随机值 //第一次调用时,回来就销毁ret, 重新创建栈帧, 第二次打印出随机值
引用和多态
1.指针和引用的定义和性质区别:
(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。如:
int a=1;int *p=&a;//定义了一个整形变量和一个指针变量p,p的值是a存储单元的地址。 int a=1;int &b=a;//定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
(2)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
(3)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
(4)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。
(5)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;
(6)指针和引用的自增(++)运算意义不一样;
2.指针和引用作为函数参数进行传递时的区别:
(1)指针作为参数进行传递:
#include<iostream>using namespace std;void swap(int *a,int *b){ int temp=*a; *a=*b; *b=temp;}int main(void){ int a=1,b=2; swap(&a,&b); cout<<a<<" "<<b<<endl; system("pause"); return 0;}
结果为2 1;
用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。
再看一个程序:
#include<iostream>using namespace std;void test(int *p){ int a=1; p=&a; cout<<p<<" "<<*p<<endl;}int main(void){ int *p=NULL; test(p); if(p==NULL) cout<<"指针p为NULL"<<endl; return 0;}
运行结果为:
0x22ff44 1
指针p为NULL
大家可能会感到奇怪,怎么回事,不是传递的是地址么,怎么p会是NULL?事实上,在main函数中声明了一个指针p,并赋值为NULL,当调用test函数时,事实上传递的也是地址,只不过传递的是指地址。也就是说将指针作为参数进行传递时,事实上也是值传递,只不过传递的是地址。当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,即上面程序main函数中的p何test函数中使用的p不是同一个变量,存储2个变量p的单元也不相同(只是2个p指向同一个存储单元),那么在test函数中对p进行修改,并不会影响到main函数中的p的值。
如果要想达到也同时修改的目的的话,就得使用引用了。
2.将引用作为函数的参数进行传递。
在讲引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以在用引用进行参数传递时,不仅节约时间,而且可以节约空间。
看下面这个程序:
#include<iostream>using namespace std;void test(int &a){ cout<<&a<<" "<<a<<endl;}int main(void){ int a=1; cout<<&a<<" "<<a<<endl; test(a); system("pause"); return 0;}
输出结果为: 0x22ff44 1
0x22ff44 1
再看下这个程序:
这足以说明用引用进行参数传递时,事实上传递的是实参本身,而不是拷贝。
所以在上述要达到同时修改指针的目的的话,就得使用引用了。
#include<iostream>using namespace std;void test(int *&p){ int a=1; p=&a; cout<<p<<" "<<*p<<endl;}int main(void){ int *p=NULL; test(p); if(p!=NULL) cout<<"指针p不为NULL"<<endl; system("pause"); return 0;}
输出结果为:0x22ff44 1
指针p不为NULL
- 指针和指针引用
- 指针和指针引用
- 指针和指针的引用
- 指针和指针的引用
- 指针,和指针的引用
- 指针和指针的引用
- 引用和指针小结
- 指针和引用
- 区分指针和引用
- 指针和引用
- 指针和引用
- 指针和引用
- 指针和引用
- 引用和指针
- 函数指针和引用
- 引用和指针
- 引用和指针
- 引用和指针
- CentOS6系统安装最新版本Node.js环境及相关文件配置
- C++11: 范围for循环
- vs2015开发.net core的环境准备
- The Knowledge of Linux-.-Day02
- 19 信号灯semaphore 1
- 引用和指针
- struets标签<S:iterator>迭代器
- struts2注解总结----@Action和@Result
- HTTP长连接和短连接原理浅析
- 【LeetCode】 274. H-Index
- Boosting和GBT
- Note7燃损确因电池而起三星将加强安全检查工作
- Hibernate中的二级缓存
- SpringMVC(第二天 高级知识)