• C++中的引用


    引用,用途是对变量取别名,本质是一个指针常量。

    1.初始化

    &写在左侧为引用,写在右侧为取地址,引用用法:Type &别名 = 原名。

    1 void test01(){
    2     int a = 10;
    3     int &b = a;
    4     b = 20;
    5     cout << a << " " << b << endl;
    6 }

    引用必须初始化,另外初始化后不能再修改指向其他变量

    1 void test02(){
    2     //int &a; //报错error C2530:引用必须初始化
    3     int a = 10;
    4     int &b = a;
    5     int c = 20;
    6     //int &b = c; 不能修改初始化的指向,会报错重定义
    7     b = c;
    8 }

    对数组起别名

     1 void test03(){
     2     //第一种方式
     3     int a[10];
     4     for (int i = 0; i < 10; ++i){
     5         a[i] = i;
     6     }
     7     int(&arr)[10] = a;
     8 
     9     //第二种方式,通过typedef
    10     typedef int(INTARR)[10];
    11     INTARR &myAr = a;
    12 }

    2.参数传递方式

    引用传参和地址传参的作用是一样的,都是为了修改变量值,其中引用后面的a和b相当于地址传参中的*a和*b。

     1 void swap01(int *a, int *b){
     2     //----------
     3     //int c = 0;
     4     //int *temp = &c;  5     //*temp = *a;
     6     //*a = *b;
     7     //*b = *temp;
     8     //----------
     9     int temp = *a;
    10     *a = *b;
    11     *b = temp;
    12     cout << *a << " " << *b << endl;
    13 }
    14 
    15 void swap02(int &a, int &b){
    16     int temp = 0;
    17     temp = a;
    18     a = b;
    19     b = temp;
    20     cout << a << " " << b << endl;
    21 }

    3.使用注意事项

    (1)引用必须引一块合法的内存空间,也不是引用NULL

    (2)不要返回局部自动变量的引用

     1 int  &test04(){
     2     //int &a = 10;
     3 
     4     //------------
     5     //int c = 10;
     6     //int &b = c;
     7     //return b;
     8     //------------
     9 
    10     int a = 10;
    11     return a;
    12 }

    第2行显示了引用一块非法的内存空间,4-8行和10-11行是返回局部变量的引用,这种返回值可能会因为编译器的优化,使得第一次可以成功返回,但多返回几次就会报错。

    (3)函数的返回值为引用,这个函数调用可以作为左值

    int main(){
    	
    	test04() = 20; //相当于a = 20
    	int a = test04();
    }
    

     4.引用的本质 

    引用的本质是指针常量。

    1 Type &ref = val; //Type *const ref = &val
    2 
    3 int a = 10;
    4 int &b = a;//自动转换为int *const b = &a,指针常量必须初始化,因此引用必须初始化
    5 b = 20; //内部发现b是引用,自动帮我们转换:*b = 20;

    5.指针引用 

    一般的二级指针 Type **p可以改写成Type *&p

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct Person{
     5     int age;
     6 };
     7 
     8 void allocMemory(Person **p){
     9     *p = (Person*)malloc(sizeof(Person));
    10     (*p)->age = 100;
    11 }
    12 
    13 void test05(){
    14     Person *p = NULL;
    15     allocMemory(&p);
    16     cout << p->age << endl;
    17 }
    18 
    19 void allocMemoryRef(Person *&p){
    20     p = (Person*)malloc(sizeof(Person));
    21     p->age = 200;
    22 }
    23 
    24 void test06(){
    25     Person *p = NULL;
    26     allocMemoryRef(p);
    27     cout << p->age << endl;
    28 }
    29 
    30 int main(){
    31     
    32     test05();
    33     test06();
    34     system("pause");
    35     return 0;
    36 }

    6.常量引用 

    通过一个例子引入常量引用

    1 void test(){
    2     //int &a = 10; // 引用不合法的空间
    3     const int &a = 10; //会分配内存,编译器进行处理 int tmp = 10; const int &a = tmp;
    4     int *p = (int *)&a;
    5     *p = 100;
    6     cout << a << endl; //a被修改
    7 }

    其实上面的代码使用的比较少,一般多用const Type &ref进行形参使用,使用常量引用形参的好处:(1)使用引用作为形参,不会产生新的变量,减少形参和实参传递的开销;(2)使用引用可能会导致实参随着形参的改变而改变。声明为const之后就会消除这种副作用。

  • 相关阅读:
    进制详解:二进制、八进制和十六进制
    学编程难吗?多久能入门?
    英语和数学不好,能学编程吗?
    C语言是菜鸟和大神的分水岭
    C语言究竟是一门怎样的语言?
    通俗地理解什么是编程语言
    哪款C语言编译器(IDE)适合初学者?
    spring task
    spring静态工厂方法得到单例bean
    多个切面表达式
  • 原文地址:https://www.cnblogs.com/qinguoyi/p/10206110.html
Copyright © 2020-2023  润新知