当前位置: 首页 > news >正文

C++中 引用与取地址的区别

引用是给已定义的变量起别名

引用:在声明的时候一定要初始化

#include <iostream>
 
using namespace std;
 
int main()
{
    int a = 88;
    int &c = a;  //声明变量a的一个引用c,c是变量a的一个别名,如果引用,声明的时候一定要初始化
    int &d = a;  //引用声明的时候一定要初始化,一个变量可以有多个引用
    
    cout<<"a="<<a<<endl;
    cout<<"c="<<c<<endl;
    cout<<"====================="<<endl;
    c=99;
    cout<<"a="<<a<<endl;
 
    return 0;
}

&(引用)==>用来传值出现在变量声明语句中位于变量 左边时,表示声明的是引用。

&(取地址运算符)==>用来获取首地址,在给变量赋初值时出现在等号右边或在执行语句中作为一元运算符出现时,表示取对象的地址.

总而言之和类型在一起的是引用和变量在一起的是取址

实例如下:1)引用在赋值=的左边,而取地址在赋值的右边,比如

int a=3;
int &b=a;        //引用
int *p=&a;        //取地址

  2)和类型在一起的是引用,和变量在一起的是取址。 举例同样如上,还有下例:

int function(int &i)
{
}  //引用

3)对于vector,上面2条同样适合

vector<int> vec1(10,1);  //initialize vec1: 10 elements, every element's value is 1
vector<int> &vec2 = vec1; // vec2 is  reference to vec1
vector<int> *vec3 = &vec2; //vec3 is addresss of vec1 and vec2

--指针-对于一个类型T,T*就是指向T的指针类型(指针只是指向首地址,即第一个字节,一般情况下,变量或对象占多个字节,而占多少字节是由类型决定的,所有指针定义时要说明类型,也即一个T*类型的变量能够保存一个T对象的地址,而类型T是可以加一些限定词的,如const、volatile等等。见下图,所示指针的含义

char c = 'a';

char *p = &c; //p里面存放的是c的地址

--引用-引用是一个对象的别名,主要用于函数参数和返回值类型,符号X&表示X类型的引用。见下图,所示引用的含义:

int i=1;

int &r = i;    //此时i=r=1

若执行r=2;//此时i=r=2

int *p = &r;  //p指向r;

指针和引用的区别

1.首先,引用不可以为空,但指针可以为空。前面也说过了引用是对象的别名,引用为空——对象都不存在,怎么可能有别名!故定义一个引用的时候,必须初始化。因此如果你有一个变量是用于指向另一个对象,但是它可能为空,这时你应该使用指针;如果变量总是指向一个对象,i.e.,你的设计不允许变量为空,这时你应该使用引用。而声明指针是可以不指向任何对象,也正是因为这个原因,使用指针之前必须做判空操作,而引用就不必。

2.其次,引用不可以改变指向,对一个对象"至死不渝";但是指针可以改变指向,而指向其它对象。说明:虽然引用不可以改变指向,但是可以改变初始化对象的内容。例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容。

3.再次,引用的大小是所指向的变量的大小,因为引用只是一个别名而已指针是指针本身的大小,4个字节

4.最后,引用比指针更安全。由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。const 指针虽然不能改变指向,但仍然存在空指针,并且有可能产生野指针(即多个指针指向一块内存,free掉一个指针之后,别的指针就成了野指针)

总之,用一句话归纳为就是:指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名,引用不改变指向。

相关文章:

  • C/C++语言中函数参数传递的三种方式(x,*x,x)
  • VC 和 VS 区别
  • 什么是Windows API
  • c++类与对象用多文件编写以及vs的操作步骤
  • DUMPBIN工具的使用
  • DLL的创建和使用(含代码)
  • _T() 函数
  • DirectUI
  • 托管与非托管
  • 什么是回调函数?
  • ShowWindow与UpdateWindow
  • VS2015无法打开源文件#include “iostream.h“的解决方法
  • BHO
  • 开放平台
  • js(=>) 箭头函数
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 0x05 Python数据分析,Anaconda八斩刀
  • es6(二):字符串的扩展
  • PAT A1017 优先队列
  • pdf文件如何在线转换为jpg图片
  • spark本地环境的搭建到运行第一个spark程序
  • vue 配置sass、scss全局变量
  • vue-loader 源码解析系列之 selector
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 复习Javascript专题(四):js中的深浅拷贝
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 前端之Sass/Scss实战笔记
  • 手写双向链表LinkedList的几个常用功能
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 【云吞铺子】性能抖动剖析(二)
  • ​secrets --- 生成管理密码的安全随机数​
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)创业家杂志:UCWEB天使第一步
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .Net Core 中间件验签
  • .net 简单实现MD5
  • .NET 药厂业务系统 CPU爆高分析
  • .NET企业级应用架构设计系列之开场白
  • .NET序列化 serializable,反序列化
  • .NET与 java通用的3DES加密解密方法
  • .NET中 MVC 工厂模式浅析
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @Autowired多个相同类型bean装配问题
  • @media screen 针对不同移动设备
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • @Repository 注解
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ NOI 2001 ] 食物链
  • [28期] lamp兄弟连28期学员手册,请大家务必看一下