首页 > 代码库 > C++ 引用(1)
C++ 引用(1)
一、什么是引用?
# 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; }
运行结果:
由此看出 ,引用更为方便!
C++ 引用(1)