【C++】引用

引用是变量的别名,必须在创建时初始化且不能为空。它与指针的不同在于引用一旦绑定到变量后不能改变,而指针可以改变所指向的对象。引用常用于函数参数以避免值复制的开销,特别是处理大对象时,也可作为返回值,但不应返回局部变量的引用。常量引用用于保护形参不被修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引用的概念

引用是一个特点的变量的另一个名字(别名)。因此,指代一个变量时,可以使用它的变量名称/引用名称。

如图所示,a的引用是b,二者指向同一块存储空间,输出b和输出a的结果是一样的。

引用和指针的区别

  • 不存在空引用。引用必须连接到一块合法的内存。但存在空指针。

  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。

  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

引用的注意事项

引用必须初始化
int a=10;
int &b;
b=a;
错误
引用一旦初始化后不能更改
引用一旦和某个变量关联起来,便会一直指向该变量
int a = 10;
int& b = a;
int c = 20;
b = c; //赋值操作,不是更改引用

可以看出,虽然调用b=c使得后引用的b的值发生了更改,但是b所指向的空间还是指向了a,没有改变。因此,b=c只是赋值操作,把c的值赋给了引用b所指向的变量,并没有改变引用b的指向。

引用必须指向一块合法的空间
int a=10;
int &ret=10; //错误,必须引用到一块合法的内存空间 

引用的两个常用功能

把引用作为函数参数

在C语言中,函数传参通常有两种形式,值传递和址传递。

void swap(int a, int b);//声明
swap(a,b); //传值,形参只是实参的一份临时拷贝,实参值无法改变
void swap(int *a, int *b);
swap(&a,&b);//传址,形参是指针变量,指向实参变量的空间,可以改变实参值

C++,为优化指针修改实参方式,特推出传变量引用这一方式。

void swap(int &a, int &b);
swap(a,b); //传引用,形参是实参的引用,和实参是同一个变量。改变形参就是改变实参。

应用:结构体传参

struct Demo 
{
  char name[10000];
  int  count;
};

int main()
{
  Demo my_demo = {0};
  Demo *my_demo_p = &my_demo;
  Demo &my_demo_ref = my_demo;
  
  // 方式1:传递实参  
  func1(my_demo);

  // 方式2:传递指针  
  func2(my_demo_p);

  // 方式3:传递引用  
  func3(my_demo_ref);

  return 0;
}
如上所示,参数传递可以有三种方式,则三种函数可以这样定义:

// 方式1:传递实参 
void func1(Demo demo)
{
  cout << demo.name;
}

// 方式2:传递指针  
void func2(const Demo *demo_p)
{
  cout << demo->name;
}

// 方式3:传递引用  
void func3(const Demo &demo_ref)
{
  cout << demo.name;
}

从内存使用的角度来说,传递实参,则会将数据拷贝过去(创建了副本),即 func1 对传入的数据做任何修改,都不会影响 my_demo。

既然传递实参要创建副本,就意味着效率更低。例子中结构体的 name 成员长度为 10000,就是要突出这个效率问题。

选择成员的时候,引用使用点 . 来查找,而指针则使用 -> 来查找

指针可能传递一个 NULL 过来,因此在使用前必须检查有效性;引用则必然代表某个对象,不需要做此检查。

把引用作为返回值
不要返回局部变量的引用:
int& test()
{
    int a=10;
    return a;
}
......
int& ret = test();
cout << "ret = "<<ret<< endl;
cout << "ret = "<<ret<< endl;
解释:
在函数test()中,变量a为局部变量,存储在栈上,函数调用完成后,变量销毁。而由于函数返回该局部变量的引用,因此该引用在函数调用完成后便无所指向,它的值是随机的。
函数调用做左值:

当函数返回一个引用时,相应的也就是返回一个特定变量的别名,此函数=常量 可用作修改特定变量值。

int vals[] = {10, 12, 33, 24, 50};
int& changevalue(int i)
{
    int& ref=vals[i];
    return vals[i];
}
changevalue(0)=1; //修改vals[0]=1
常量引用:

常量引用主要用于修饰形参,用const修饰形参,避免误操作更改值

void show( const int &val) 
//在函数中,常常因为误操作更改实参的值,加入const后,传入的相应实参值不会发生改变。
{
    ....
    cout<< val<< endl;
}
int num=1;
show(num);  //传入num实参,意图打印num

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值