标签:引用
一、什么是引用?
# include<iostream>
using namespace std;
int main()
{
int num;
int &mum=num;
//这就好像李四有个外号叫李大嘴,大家称呼李四指的是李四这个人,称呼李大嘴也是指的是李四这个人,李四和李大嘴都是一个人,只是名字不同而已。
//对num的操作也就是对mum的操作,&mum不是取地址符,而是引用符号。他们的符号相同,但是功能不同。应用就是别名。
num=999;
cout<<"num的值为:"<<num<<endl;
cout<<"mum的值为:"<<mum<<endl;
num=100;
cout<<"num的值为:"<<num<<endl;
cout<<"mum的值为:"<<mum<<endl;
return 0;
}
二、引用的地址
# include<iostream>
using namespace std;
int main()
{
int a;
int &ra=a;
cout<<"a的地址为:"<<&a<<endl;
cout<<"ra的地址为:"<<&ra<<endl;
return 0;
}
注释:因此对ra的操作就是对a的操作。因为他们的地址是一样的。
三、引用就是别名常量
# include<iostream>
using namespace std;
int main()
{
int a;
int &ra=a;
a=555;
cout<<"a的地址为:"<<&a<<endl;
cout<<"ra的地址为:"<<&ra<<endl;
cout<<"a的值为:"<<a<<endl;
cout<<"ra的值为:"<<ra<<endl;
int b=999;
ra=b;
cout<<"a的地址为:"<<&a<<endl;
cout<<"ra的地址为:"<<&ra<<endl;
cout<<"b的地址为:"<<&b<<endl;
cout<<"a的值为:"<<a<<endl;
cout<<"ra的值为:"<<ra<<endl;
cout<<"b的值为:"<<b<<endl;
//把b的值付给ra,那么a和ra的值都给改变了,但是地址并没有变化。
ra=100;
cout<<"a的值为:"<<a<<endl;
cout<<"ra的值为:"<<ra<<endl;
cout<<"b的值为:"<<b<<endl;
//a和ra的值又便换来了。
//在这个实例中,我们将ra定义为a的值,ra只是属于a,但是他不会因为b而变成b的别名,但是他会因为b的赋值,把变量a也变成b的值。
//ra是a的别名,我们不能改变,但是我们却可以改变ra的值,这样还会导致a的值得改变。
return 0;
}运行结果:
四、引用对象
# include<iostream>
using namespace std;
class Human
{
public:
int get(){return i;}
void set(int x){i=x;}
private:
int i;
};
int main()
{
Human Mike;
Human &rMike=Mike;
//对象的别名
//Human &rHuman=Human;
//以上是错误的,我们不能定义类的引用。Human是一个类,他们有具体的内存地址,我们不能定义一个类的引用。
rMike.set(123);
cout<<rMike.get()<<endl;
//以上看来,rMike是和MIke一样的。
return 0;
}五、空引用
我们知道指针进行删除操作后,需要将它们赋为空,引用却不需要这么做,这是因为引用是原来对象的别名,假如该对象存放在栈中,那么在对象超出作用域时别名会和对象一起消失。假如该对象存放在堆中,由于堆中内存空间必须使用指针来访问,因此用不着别名,即使再定义一个该指针的别名,那么将指针删除并赋空之后,该指针的别名中的地址也相应的赋空了。
六、按值传递
# include<iostream>
using namespace std;
void swap(int a,int b)
{
int c;
cout<<"swap函数中,交换前,a:"<<a<<"\t"<<"b:"<<b<<endl;
c=a;
a=b;
b=c;
cout<<"swap函数中,交换后,a:"<<a<<"\t"<<"b:"<<b<<endl;
}
int main()
{
int a=3,b=4;
cout<<"主程序中,交换前,a:"<<a<<"\t"<<"b:"<<b<<endl;
swap(a,b);
cout<<"主程序中,交换后,a:"<<a<<"\t"<<"b:"<<b<<endl;
return 0;
}
注释:
以上这个问题很简单,swap函数交换的是main函数中a和b的副本的值;也就是说在main函数中定义的a和b的备份的值;swap函数交换的是main函数中的a和b的副本,而不是a和b本身;这是因为当我们直接将a和b传递给swap函数时,这样的传递是按值传递;假如将a和b按值传递给swap函数,那么编译器会自动在栈中创建a和b的拷贝,然后将a和b的拷贝传递给swap函数。在swap函数中对a和b的拷贝进行交换。因此我们看到的输出语句,a和b确实进行了交换,只不过交换的是a和b的副本。由于交换的是a和b的副本,并不是a和b本身,所以在swap函数结束后,输出的值显示main函数中的a和b并没有改变。
七、按址传递
# include<iostream>
using namespace std;
void swap(int *a,int *b)
{
int c;
//以下是交换主函数中a和b的值,所以要带*。
cout<<"swap函数中,交换前,a:"<<*a<<"\t"<<"b:"<<*b<<endl;
c=*a;
*a=*b;
*b=c;
cout<<"swap函数中,交换后,a:"<<*a<<"\t"<<"b:"<<*b<<endl;
}
int main()
{
int a=3,b=4;
cout<<"主程序中,交换前,a:"<<a<<"\t"<<"b:"<<b<<endl;
swap(&a,&b);
//传递的是a和b的地址。
cout<<"主程序中,交换后,a:"<<a<<"\t"<<"b:"<<b<<endl;
return 0;
}
//通过地址的传递,我们能直接访问到a和b的地址,因此修改的也是a和b的值,而不是他们的副本。
八、按别名传递
# include<iostream>
using namespace std;
void swap(int &a,int &b)
//这里的a和b不是主函数中的a和b,这里的a和b是主函数a和b的别名,传递的是主函数中a和b中的别名,这个比址传递还要简单。
//通过a和b的别名可以交换a和b的值。
{
int c;
cout<<"swap函数中,交换前,a:"<<a<<"\t"<<"b:"<<b<<endl;
c=a;
a=b;
b=c;
cout<<"swap函数中,交换后,a:"<<a<<"\t"<<"b:"<<b<<endl;
}
int main()
{
int a=3,b=4;
cout<<"主程序中,交换前,a:"<<a<<"\t"<<"b:"<<b<<endl;
swap(a,b);
cout<<"主程序中,交换后,a:"<<a<<"\t"<<"b:"<<b<<endl;
return 0;
}
九、利用指针返回多值
# include<iostream>
using namespace std;
int func(int a,int *b,int *c);
int main()
{
int a=1,b=2,c=3;
cout<<"主程序,调用func函数前...\n";
cout<<"a:"<<a<<endl<<"b:"<<b<<endl<<"c:"<<c<<endl;
func(a,&b,&c);
cout<<"主程序,调用func函数后...\n";
cout<<"a:"<<a<<endl<<"b:"<<b<<endl<<"c:"<<c<<endl;
//a是值传递,b和c是地址传递
return 0;
}
int func(int a,int *b,int *c)
{
cout<<"func函数中,计算前...\n";
cout<<"a:"<<a<<endl<<"b:"<<*b<<endl<<"c:"<<*c<<endl;
a=a+1;
*b=(*b)*(*b);
//用过b的地址传递,把b的值平方再付给b
*c=(*c)*(*c)*(*c);
cout<<"a:"<<a<<endl<<"b:"<<*b<<endl<<"c:"<<*c<<endl;
return a;
}
虽然是返回了a值,但是我们可以到是返回了3个值,因为b和c的值也改变了。
我们可以把a看作是返回的判断值,b和c看做运算的返回值。
用该方法我们可以实现汇报执行程序时的非法操作信息。
# include<iostream>
using namespace std;
int func(int a,int *b,int *c);
int main()
{
int a,b,c;
int check;
cout<<"请您输入要进行运算的数字,";
cout<<"您输入的数字将作为园的半径和正方形的边长:";
cin>>a;
check=func(a,&b,&c);
if(check)
{
cout<<"输入的数字超过计算范围!\n";
}
else
{
cout<<"圆的面积为:"<<b<<endl;
cout<<"正方形的面积为:"<<c<<endl;
}
return 0;
}
int func(int a,int *b,int *c)
{
if(a>20000)
{
a=1;
}
else
{
*b=a*a*3.14;
*c=a*a;
a=0;
}
return a;
}
但是我们要注意的是:这两个值不是通过返回机制来得到实现的,而是通过改变函数指针参量*b和*c所指向的内存区域中的值来实现的。
十、利用引用来返回多值以上程序用引用更为方便
# include<iostream>
using namespace std;
int func(int a,int &b,int &c);
int main()
{
int a,b,c;
int check;
cout<<"请您输入要进行运算的数字,";
cout<<"您输入的数字将作为园的半径和正方形的边长:";
cin>>a;
check=func(a,b,c);
if(check)
{
cout<<"输入的数字超过计算范围!\n";
}
else
{
cout<<"圆的面积为:"<<b<<endl;
cout<<"正方形的面积为:"<<c<<endl;
}
return 0;
}
int func(int a,int &b,int &c)
{
if(a>20000)
{
a=1;
}
else
{
b=a*a*3.14;
c=a*a;
a=0;
}
return a;
}
由此看出 ,引用更为方便!
标签:引用
原文地址:http://blog.csdn.net/cyksky/article/details/42342395