C++---引用的基础知识

 

1.引用

1.1 定义

引用就是变量的别名(并没有重新定义一个变量),通过将声明符写成&d的形式来定义引用类型。需注意的是:

  • 一个变量可以有多个别名;
  • 引用的变量必须初始化;
  • 引用只能在初始化的时候使用一次,不能再引用改变其他变量

如下所示,已定义变量a,b与c相当于a的别名,即a可以叫b,也可以叫c;b、c与a指向同一块空间,当其中一个改变时,其他的值也跟着改变

int main()
{
    int a=1;
    int &b=a;
    int &c=b;
    std::cout<<a<<" "<<b<<" "<<c<<std::endl;//1 1 1
    b=2;
    std::cout<<a<<" "<<b<<" "<<c<<std::endl;//2 2 1
}

注:&在类型之后、变量之前为“引用”;&在比那里之前为“取地址”

1.2 const引用

原则:属性只能被局部缩小,不能被局部放大

(1)常引用量可以引用可被修改的量

int a=2;
const int &b=a;//正确

(2)常量具有常性,只有常引用才能引用常量,可被修改的量不能引用常量

const int a=2;
const int &b=a;//正确
//int &b=a;//错误

(3)e的类型是double,f的类型是int,e赋值给f时系统生成一个临时变量,即这个临时变量具有常性不能被修改,所以不能赋值;

          又e和f指向的是两个变量,所以e的改变不影响f

double e=1.2;
const int& f=e;
std::cout<<e<<" "<<f<<std::endl;//1.2 1
e=2.3;
std::cout<<e<<" "<<f<<std::endl;//2.3 1

double e2=1.2;
int &f2=e2;
std::cout<<e2<<" "<<f2<<std::endl;//1.2 1

1.3引用做参数

函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

当形参和实参不是指针类型时,在该函数运行时,形参和实参是不同的变量,他们在内存中位于不同的位置,形参将实参的内容复制一份,在该函数运行结束的时候形参被释放,而实参内容不会改变。 

void swap(int a,int b)
{
    int c=a;
    a=b;
    b=c;
}
int main()
{
    int c=10;
    int d=20;
    swap(c,d);
    std::cout<<c<<" "<<d<<std::endl;//10 20
    return 0;
}

 

如果函数的参数是指针类型变量,在调用该函数的过程中,传给函数的是实参的地址,在函数体内部使用的也是实参的地址,即使用的就是实参本身。所以在函数体内部可以改变实参的值。

void swap2(int& a, int& b)
{
	int c = a;
	a = b;
	b = c;
}

int main()
{
	int c = 10;
	int d = 20;
	
	swap2(c, d);
	std::cout << c << " " << d << std::endl;//20 10
	return 0;
}

 

1.4 引用做返回值

int add1(int a, int b)
{
	int c = a + b;
	return c;
}


int& add2(int a,int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int tmp1 = add1(10, 20);
	std::cout << tmp1<< std::endl;//30
	int tmp2 = add2(30, 20);
	std::cout << tmp2 << std::endl;//50
	system("pause");
	return 0;
}

出了作用域对象不在---传值返回

出了作用域对象还在---最好传引用返回,提高效率;也可以用传值返回,开销大。

2.指针与引用的区别

(1)概念上不同:指针是地址变量,指向内存中的一个地址;引用是变量的别名,本质上还是与这个变量

(2)其他

  • 指针可以为空;引用的变量不可以为空,引用在定义时变量必须初始化,且引用只能在初始化时使用一次,之后不能再指向其它对象
  • 指针可以有一级、二级、多级指针,如int **a;引用只能有一级,不存在int &&a
  • 有const指针,没有const引用
  • 指针++是对指向内存中的地址++;引用++是对这个变量进行++
  • “sizeof指针”得到的是指针本身的大小;“sizeof引用”得到的是所指向变量的大小
  • 引用做参数传递的是实参本身,指针做参数传递的是实参的地址

不是实参的拷贝,形参相当于实参的别名,对形参修改就是对实参修改;

 指针做参数传递的是实参的地址,指针实际上是无存储实参内存单元里的数据,从而达到对实参修改的目的。

  • 指针比引用更灵活,引用比指针更安全

对++,--这样的操作,引用永远只能指向一个地方,而且是在初始化的时候指定,而指针可以指向其它地方。

调用某一类型空悬指针(指针的值不为空,但它指向的内容有可能被delete了),指针不会知道它所指的内容为空,调用时有可能导致系统崩溃。而引用所指内容绝对不能为空,有效防止了这一点。

3.有了指针为什么还要有引用

“引用传递”的性质像“指针传递”,而书写方式像“值传递”。实际上“引用”可以做的任何事情“指针”也都能够做,但是指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。

指针经常犯的错误有:1,操作空指针,2,操作野指针,3,不知不觉改变了指针的值,而后还以为该指针正常。如果我们要正确的使用指针,我们不得不人为地保证这三个条件。而引用的提出就是解决这个问题。引用区别于指针的特性是:1,不存在空引用(保证不操作空指针),2,必须初始化(保证不是野指针),3,一个引用永远指向他初始化的那个对象(保证指针值不变)。所以引用的提出就是尽可能减少错误的产生。

使用原则:尽可能使用引用,不得已时使用指针。

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值