C++:引用reference

目录

一、引用 reference

1.1 引用的概念

1.2 引用的性质

1.3 引用参数

1.4 指针与引用的区别

1.语法层面的区别

2. 汇编层面的区别


一、引用 reference

1.1 引用的概念

引用与指针非常相似,但是弱化了程序员对内存的控制,引用已经被其它的面向对象编程语言大量使用,这些编程语言都删除了指针。C++同时支持指针与引用。编译器不会为引用变量开辟内存空间,它与引用的变量共用同一块内存空间。

引用使用&来表示一个变量的“别名”,对引用进行操作与直接操作变量完全一样。

引用格式:

类型 & 引用变量名(对象名) = 引用实体
注意这里的空格是可选的,即

  • &符号与前后均可以有一个空格;如下:int & ra=a;
  • &符号与类型挨着,如下:int& ra=a;
  • &符号与引用名称挨着,如下:int &ra=a;
#include <iostream>

using namespace std;


int main()
{
    int a = 100;
    // b是a的引用
    int& b = a;
    cout << "地址:" << &a << " " << &b << endl; // 0x61fe88 0x61fe88
    b++;
    cout << a << endl; // 101

    return 0;
}

1.2 引用的性质

  • 可以改变引用的变量的值,但是不能再次成为其它变量的引用
#include <iostream>

using namespace std;


int main()
{
    int a = 100;
    // b是a的引用
    int& b = a;
    int c = 200;
    b = c; // b不会成为c的引用,只是完成了赋值
    cout << &a << " " << &b << " " << &c << endl; // 0x61fe78 0x61fe78 0x61fe74
    cout << a << " " << b << " " << c << endl; // 200 200 200

//    &b = c;   错误
//    int& b = c; 错误

    return 0;
}
  • 声明引用时,必须同时对其进行初始化。
#include <iostream>

using namespace std;


int main()
{
    int a = 100;
//    int& b; 错误
    int& b = a;

    return 0;
}

  • 声明引用时,初始化的值不能是NULL
#include <iostream>

using namespace std;


int main()
{
//    int& b = NULL; 错误

    return 0;
}

  • 声明引用时,初始化的值可以使纯数值,但是此时需要使用const关键字修饰引用,表示引用的值不可变,也称为“常引用”。
#include <iostream>

using namespace std;


int main()
{
//    int& b = 200; 错误
    // b是常引用
    const int& b = 200;
//    b++;  错误
    cout << b << endl;

    return 0;
}

  • 可以将变量引用的地址赋值给一个指针,此时指针指向的还是原来的变量。
#include <iostream>

using namespace std;


int main()
{
    int a = 10;
    int& b = a;
    int* c = &b; // c指向b,b是a的引用,相当于c指向了a
    cout << *c << endl; // 10

    return 0;
}

  • 可以建立指针的引用
#include <iostream>

using namespace std;


int main()
{
    int a = 10;
    int* b = &a; // b指向了a
    int*& c = b; // c是b的别名
    cout << c << " " << b << endl; // 0x61fe88 0x61fe88
    cout << *c << " " << *b << endl; // 10 10

    return 0;
}

  • 可以用const修饰引用,此时不允许改变引用的值,但是可以改变原变量的值。

#include <iostream>

using namespace std;


int main()
{
    int a = 10;
    const int& b = a; // b是a的常引用
//    b++; 错误
    a++;
    cout << a << " " << b << endl; // 11 11

    return 0;
}
 
   

1.3 引用参数

使用引用做为参数可以减少参数传递的开销,因为在参数传递的过程中不产生副本,可以使参数传递的效率提高。

【例子】使用引用参数实现一个可以交换两个数的函数。

#include <iostream>

using namespace std;

/**
 * @brief swap1 错误,因为传递参数时会生成局部副本
 */
void swap1(int a,int b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    cout << a << endl; // 2
    cout << b << endl; // 1
}

/**
 * @brief swap2 正确但繁琐
 */
void swap2(int* a,int* b)
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}

/**
 * @brief swap3 正确且简洁
 */
void swap3(int& a,int& b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}


int main()
{
    int a = 1;
    int b = 2;
    swap1(a,b);
    cout << a << endl; // 1
    cout << b << endl; // 2
    swap2(&a,&b);
    cout << a << endl; // 2
    cout << b << endl; // 1
    swap3(a,b);
    cout << a << endl; // 1
    cout << b << endl; // 2

    return 0;
}

引用参数应该在能被定义为const的情况下,尽量定义为const,这样可以达到引用的安全性。

#include <iostream>

using namespace std;

void show(const int& a,const int& b)
{
    cout << a << endl;
    cout << b << endl;
}


int main()
{
    show(1,3);

    return 0;
}

1.4 指针与引用的区别

1.语法层面的区别

  1. 从语法规则上讲,指针变量存储某个实例(变量或对象)的地址;
    引用是某个实例的别名。
  2. 程序为指针变量分配内存区域;而不为引用分配内存区域。
    ​
    int main()
    {
    	int a = 10;
    	int* ip = &a;
    	int& b = a;  \\b是a的别名 并没有分配新的空间
    }
    
    ​
  3. 指针使用时要在前加“*”;引用可以直接使用。
    int main()
    {
    	int a = 10;
    	int* ip = &a;
    	int& b = a;  
    	*ip = 100;//对于指针使用加“*”
    	b = 200;  //引用不需要“*”
    	
    }
  4. 指针变量的值可以发生改变,存储不同实例的地址;
    引用在定义时就被初始化,之后无法改变(不能是其他实例的引用)。
    int main()
    {
    	int a = 10,b = 20;
    	int* ip = &a;
    	ip = &b ;
    	int& c = a;
    	c = b;   //b的值给c实则是把b的值给a,将a的值改为20
    }
  5. 指针变量的值可以为空(NULL,nullptr);没有空引用。
  6. 指针变量作为形参时需要测试它的合法性(判空NULL);
    引用不需要判空。
  7. 对指针变量使用"sizeof"得到的是指针变量的大小;
    对引用变量使用"sizeof"得到的是变量的大小。
    ​
    int main()
    {
    	double dx = 10;
    	double* dp = &dx;
    	double& a = dx; 
    	printf("sizeof(dp):%d\n", sizeof(dp));//4
    	printf("sizeof(a):%d", sizeof(a));//8
    }
    
    ​

  8. 理论上指针的级数没有限制;但引用只有一级。
    即不存在引用的引用,但可以有指针的指针。

  9. ++引用与++指针的效果不一样

    int main()
    (
    	int ar[5] = { 1,2,3,4,5 };
    	int* ip = ar; //数组首元素地址
    	int& b = ar[O]; //数组首元素的别名叫b
    	++ip;  //由0下标的地址指向1下标的地址
    	++b;  //由0下标指向1下标
    }
    

  10. 对引用的操作直接反应到所引用的实体(变量或对象)。
    对指针变量的操作,会使指针变量指向下一个实体(变量或对象)的地址;而不是改变所指实体(变量或对象)的内容。
    int main()
    (
    	int ar[5] = { 1,2,3,4,5 };
    	int* ip = ar; //数组首元素地址
    	int& b = ar[O]; //数组首元素的别名叫b
    	++(*ip); //值由1>>2 
    	(*ip)++; //所有表达式结束后 进行++ 
    	//有括号 先取ip的值与*结合 然后++为所指之物的++
    	int x = *ip++;
    	//没有括号 先将ip的值取出 与*结合 把所指之物取出(此时已与*结合完) 然后将ip取出进行++ ++后的值回写给ip 将值存储到x中
    	//通过()提高了优先级
    }
    
  11. 不可以对函数中的局部变量或对象以引用或指针方式返回。

    当变量的生存期不受函数的影响时就可以返回地址

2. 汇编层面的区别

汇编层面来讲引用就是一个指针,但是引用并不是一个普通的指针是指针的语法槽,也可以看作是常性的指针 。

int main()
{
	int a = 10;
	int* ip = &a;
	int& x = a;
	*ip = 100;
	x = 200;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值