C++当中的引用

1、引用


    引用不是独立的数据类型,实际上是对变量起了别名.


     如: int a = 66;

              int& b = a; //相当于给a起了个别名.


 2、引用和指针的比较

      (1)变量 指针 引用

       2.1.引用必须初始化,指针可以不初始化

           int a = 66;
           int& b = a;
           int&c; //error.


        2.2.引用不能为空,指针可以为空
               int a= 66;
               int& b = NULL;                //error.
               const int& b = NULL;    //ok
               const int& b = 0;           //ok.
               int* p =NULL;              //空指针


         2.3.引用不能更改换目标,指针是可以的
                int a = 66;
                int& b = a;
                int m = 118;
                b = m; //赋值,是把m的值赋给a.


         2.4.不能声明引用型的数组,可以声明指针数组
               int a[10];
               int* pa[10];
               int& a[10] ; //error. 因为引用本身不占内存,数组要求一段连续的内存空间,所以报错


         2.5.指针和引用符号停靠问题

                2.5.1指针符号停靠问题.

                      int* p; int * p; int *p;

                      int* p ,q; //q是整型变量;

                      int *p,*q; //q指针;

              不成文的规定:当定义一个指针时,我们习惯让*靠在数据类型,当我们定义多个指针时,我们习惯让*靠在变量名称边.

              2.5.2引用符号停靠问题.

                       int a = 66;
                       int& b = a;
                       int & b = a;
                       int &b = a; //三种方法一样.


                       int c = 118;
                       int &b = a,&d = c;
                      引用符号不成文的规则同上.
                      不成文的规定:当定义一个引用时,我们习惯让&靠在数据类型,当我们定义多个引用时,我们习惯让&靠在变量名称边.





      2.6.起别名来定义

             typedef int* PINT;

             PINT i,j; //这两个都是指针

             typedef int& RINT;

             RINT r = a,s = b; //两个都是引用


             #define PINT int*
             PINT i,j; //i是指针,j是整型.


3、注意:

引用的本质还是指针,但是建议使用引用而不是指针

double d = 3.14;

double& m = d;

 ==> double* const pm = &d; 指向不能改,但指向的值是可以改的。

 ==> const double* pm = &d; 指向可以改变,但指向的值不可以改变。



      2.7.引用作为函数的参数

              小结:(1)可以定义指向指针的指针,但是不可以定义指向引用的指针

                               如:int a = 66;

                                       int* pa = &a;
                                       int** ppa = &pa; //ok
                                       int& b = a;
                                      int& *pb = &b; //error 编译器不识别 没有规定这种语法.

                          (2)可以定义引用指针的引用,不可用定义引用 引用的 引用.

                (即是可以定义指针的引用,不是不能给引用定义引用).
                int a = 66;
                        int* pa = &a;
                int*& pb = pa; //ok
                int& b = a;
                int&& c = b; //error.

                      (3)可以定义指针数组,但是不能定义引用数组. 不过可以定义数组的引用.

              int num[5]
              int* p[5];
              int& p[5]; //error
              int (&q)[5] = num //ok;
              int (*q)[5] = &num //ok;


注意: 在程序中函数的形参尽可能的加引用,尽可能的加const.
//使用引用型参数可以在函数中对实参变量做修改
//使用引用型参数可以避免参数传递过程中的数据拷贝
//尽量使用常引用,可以避免实参的值在函数中被意外改变




//8.引用作为函数的返回值:
//注意
//永远都不要返回一个局部变量(函数的形参)的引用,可以返回全局变量,静态的局部变量,成员变量
//实参的引用,动态内存。


//引用作为函数的返回值
struct S 
{
	int n;
	int& fn(void)
	{
		return n;
	}
};


int& fnReturn(void)
{
	int n = 66; //返回了局部变量的引用
	return n;
}


void daoluan(void) //捣乱
{
	int i = 100,j = 200;
}


int& fnReturnEx(void)
{
	static int num = 66;
	return num;
}


int& fnReturnExEx(int& n)
{
	return n;
}


//引用作为函数的参数
void fn6(char* & pstr)
{
	pstr = "good!";
}
void fn5(char** pstr)
{
	*pstr = "world!";
}
void fn4(char* pstr)
{
	pstr = "world!";
}
//引用传递
void fn3(int& n)
{
	n = 250;
}
//址传递
void fn2(int *p)
{
	*p = 118;
}
//值传递
int fn( int n)
{
	return n = 118;
}


void swapP(int* a,int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
void swapR(int& a,int& b)
{
	int temp  = a;
	a = b;
	b = temp;
}
void FunReferenceEx()
{
	int num = 888;
	cout<<"num = "<<num<<endl;
	cout<<"------------------------------"<<endl;
	fn(num);	//值传递
	cout<<"num = "<<num<<endl;
	cout<<"------------------------------"<<endl;
	fn2(&num);  //址传递
	cout<<"num = "<<num<<endl;
	cout<<"-------------------------------"<<endl;
	fn3(num);   //引用
	cout<<"num = "<<num<<endl;


	cout<<"--------------------------------"<<endl;
	char* pStr = "hello!";
	fn4(pStr);	//
	cout<<"pStr = "<<pStr<<endl;


	cout<<"--------------------------------"<<endl;
	fn5(&pStr);	//二级指针
	cout<<"pStr = "<<pStr<<endl;


	cout<<"--------------------------------"<<endl;
	fn6(pStr);	//一级指针的引用.
	cout<<"pStr = "<<pStr<<endl;


// 	cout<<"--------------------------------"<<endl;
// 	fn7(&pStr);	//二级指针的引用.
// 	cout<<"pStr = "<<pStr<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值