zoukankan      html  css  js  c++  java
  • C++之引用

    C++之引用

    1、什么是引用

    引用,就是为一个事物(变量、数据类型)起一个别名。实际中变量名它本身是一段内存的引用,即为该段内存起了一个名称,该段内存的名称 = 定义的变量名。

    2、为何引入引用

    • C++引入引用后,取代了指针传递参数的问题,引用就是完完全全相等的值传递。

    • C里面参数的传递是通过指针,当实参是数组时,此时用指针传递形式参数时,其实指针已经退化。(详解数组变量的引用)。

    3、引用的规则

    3.1 、 引用是一种关系型声明,而非定义。不能独立存在,必须初始化,且与原类型保持一致, 且不分配内存。

      //错误写法				//正确写法
      int a;				  int a;
      int &mya;  			  int &mya = a;
     //引用本质是声明,不能先定义,后赋值。
    

    3.2 、 引用声明关系,一经声明,不可变更。

      //错误写法				//正确写法
      int a,b;				  int a,b;
      int &mya = a;  		  int &mya = a;
      int &mya = b;			  int &myb = a;
    

    3.3 、 引用可再次引用,多次引用的结果是某一变量具有多个别名, 多个别名间是平行关系。

      int a;		
      int &mya = a;
      int &myaa = a;	
    

    3.4 、 辨别引用与其它, &前有数据类型时或&在赋值号=左边即为引用,其它皆为取地址或按位与。


    4、变量的引用及举例

    4.1、 一般变量的引用

      int a;		
      int &mya = a;  //此时操作mya完全就是操作a
    

    4.2、指针变量的引用

      int *p;
      int * &myp = p;
    

    存在问题:引用的指针是否存在?

      //不存在下列写法
      int *p;
      int * &myp = p;  		//myp是一个指针的引用
      int & * prp = &myp;  //&myp是指引用的地址
      引用的本质是指针, C++对裸露的内存地址(指针)作了一次包装。又取得了指针的优良特性。所以再对引用取地址,建立引用的指针无意义。
    

    4.3、变量的多次引用

      //即为一个变量起多个别名
      int a;		
      int &mya = a;
      int &myaa = a;
    
    • . 存在问题:引用的引用是否存在?
    //不存在下列写法
    int a;
    int & rz = a;
    int && rrz = rz; 
    

    4.3、数组变量的引用

    #include <iostream>
    using namespace std;
    void fun(int (&data)[3])
    {
        printf("sizeof(ra) = %d\n",sizeof(data));  //输出:12
    }
    void fun1(int *const &data)
    {
        printf("sizeof(pr) = %d\n",sizeof(data)); //输出:4
    }
    int main()
    {
        int array[3];
        fun(array);
        fun1(array);
        return 0;
    }
    

    总结:数组引用的形参的两种表现形式

    • int (&data)[3] //数组引用的标准形式值传递,sizeof(data) = 4*3=12。

    • int *const &data //其实已经退化为指针的引用,sizeof(data) = 4。

    1、这里必须要加const,因为数组名是一个const的类型;
    2、当数组引用时不能操作数组的引用名称如:data = 2;
    3、因为引用data是const类型的,只能操作引用内容:data[x] = 2。


    存在问题:引用数组是否存在?
    问题解析:不存在引用数组,引用只是声明,在内存中不分配内存,而数组是要分配内存的,这与引用的定义不符。
    int &a[2] = {a,b} //错误写法。

    5、常引用及举例(关键字const)

    概念:const 的本意,即不可修改。所以const变量或者对象,只能声明为 const 引用,使其语义保持一致性。


    1、 non-const变量或者对象,既可以声明为 const 引用,也可以声明为 no-const引用。声明为 const 引用,则不可以通过 const 引用修改数据。

    //non-const引用
    int data;
    int &rd = data;
    rd = 5;
    
    //const引用
    int data;
    const int &rd1 = data;
    //rd = 6; 声明为 const 引用,则不可以通过 const 引用修改数据。
    

    2、const变量或者对象必须声明为const引用。


    	const int val = 10;
    	int & rv = val; //错误写法
    	const int & rv2 = val; //正确写法
    
    

    5.1、临时对象的常引用


    临时对象:通常不可以取地址的对象,Cpu在运行计算中产生的中间变量,通常也称为右值。常见临时对象有常量,表达式等。

    #include <iostream>
    using namespace std;
    //临时变量 即不可取地址的对象
    #include <iostream>
    using namespace std;
    //临时变量 即不可取地址的对象
    //常量 表达式 函数返回值 类型不同的变量
    int foo()
    {
    	int a = 100;
    	return a;
    }
    int main1()
    {
    	//常量
    	const int & cc = 55;
    	cout<<cc<<endl;
    	//表达式
    	int a = 3; int b = 5;
    	const int &ret = a+b;
    	//函数返回值
    	const int& ra = foo();
    	//类型不同的变量
    	double d = 100.12;
    	const int &rd = d;
    	
    }
    int main1()
    {
    	//常量
    	const int & cc = 55;
    	cout<<cc<<endl;
    	//表达式
    	int a = 3; int b = 5;
    	const int &ret = a+b;
    	//函数返回值
    	const int& ra = foo();
    	//类型不同的变量
    	double d = 100.12;
    	const int &rd = d;
    	return 0;
    }	
    
    • 常引用的本质
    #include <iostream>
    using namespace std;
    
    int main()
    {
        double d = 3.14;
        const int & rd = d;       
        cout<<"d = "<<d<<endl;    
        cout<<"rd = "<<rd<<endl;
    
        d = 4.14;
        cout<<"d = "<<d<<endl;
        cout<<"rd = "<<rd<<endl;
    
        return 0;
    }
    
    输出结果:
    	3.14
    	 3
    	4.14
    	 3
    

    存在问题:为何临时变量都改变了,引用变量的内容还保持第一次的值?
    问题解析:本质上 const 引用,引用了一个不可改变的临时变量, const int tmp = data;const int &rd = tmp; 此时,我们改变了 data 的值,临时变量的值也不会改变。

  • 相关阅读:
    【leetcode❤python】 1. Two Sum
    【leetcode❤python】 67. Add Binary
    【leetcode❤python】 396. Rotate Function
    【leetcode❤python】 400. Nth Digit
    【leetcode❤python】 160. Intersection of Two Linked Lists
    【leetcode❤python】 203. Remove Linked List Elements
    【leetcode❤python】 225. Implement Stack using Queues
    Kotlin:【标准库函数】apply(配置函数)、let、run函数
    Kotlin:【字符串操作】substring、split、replace、字符串比较==与===、foreach遍历字符
    Kotlin:【针对空安全管理的操作】安全调用操作符、使用带let的安全调用、非空断言操作符(感叹号操作符)、使用if判断null值情况、使用空合并操作符(类似三元表达式)
  • 原文地址:https://www.cnblogs.com/retry/p/9308837.html
Copyright © 2011-2022 走看看