1、引用作为变量的别名存在,因此可以在一些场合代替指针。

   引用相当于指针来说具有更好的可读性和实用性。

  例如:

  

/*  编译环境
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
*/
#include <stdio.h> void sewp_C(int *a, int *b) //使用指针进行 a 和 b 之间的交换。
{
int t;
t = *a;
*a = *b;
*b = t;
} void sewp_C_fun(int &a,int &b)//使用 引用实现 a 和 b之间的交换
{
int t = a;
a = b;
b = t;
} int main(int argc, char *argv[])
{
int a = ,b = ;
printf("Begin...\n");
sewp_C(&a,&b);
printf("a = %d\tb = %d\n",a,b); //打印结果 a = 0 b = 1
sewp_C_fun(a,b);
printf("a = %d\tb = %d\n",a,b); //打印结果 b = 1 a = 0
printf("End...\n");
return ;
}

  运行结果:

Begin...
a = b =
a = b =
End...

 通过两种方式实现,两个数内容的交换。 使用指针调用函数则为:sewp_C(&a,&b);    而使用引用则为:sewp_C_fun(a,b);  这样看起来更加直观。

  注意:在函数形参中的引用可以不用初始化。

特殊的引用:const 引用

  在C++中声明const  引用格式: const Type & name = var;

  const 引用可以让变量具备 只读属性

/*  编译环境
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
*/
#include <stdio.h> int main(int argc, char *argv[])
{ printf("Begin...\n");
int a = ;
const int & b = a;
int* p = (int*) &b; //b = 10;//错误 变量拥有只读属性
*p = ;
printf("a = %d\tb = %d\n",a,b); //打印结果 a = b = 20
printf("End...\n"); return ;
}

   运行结果:

Begin...
a = b =
End...

  如果将 const int & b = a; 替换成 :const int & b = 1; 这样将使用一个常量来初始化引用。

  

引用是否有自己的存储空间?
  

  

#include <stdio.h>

struct Tqr
{
char & r;
}; int main(int argc, char *argv[])
{
char c = 'c';
char & rc = c;
Tqr ref ={c};
int *p;
printf("Begin...\n");
printf("sizeof(char &) = %d\n",(int)sizeof(char &)); // 打印变量char &所占用的大小 占用一个字节
printf("sizeof(rc) = %d\n",(int)sizeof(rc)); // rc 占用一个字节
printf("sizeof(Tqr) = %d\n",(int)sizeof(Tqr)); //占用4个字节
printf("sizeof(ref.r) = %d\n",(int)sizeof(ref.r)); //ref.r 占用1个字节 (字符变量)
printf("sizeof(p) = %d\n",(int)sizeof(p)); printf("End...\n");
return ;
}

  打印结果:  

Begin...
sizeof(char &) =
sizeof(rc) =
sizeof(Tqr) =
sizeof(ref.r) =
sizeof(p) =
End...

  可以看出,Tqr 所占的空间为4 所以引用是占用4个字节的大小的。

  所以可以猜测 引用 在C++中的实现就应该是使用指针来实现的。

  

引用的意义:其主要作用在大多数情况下是为了代替指针。

  可以满足多数需要使用到指针的场合。

  可以避开由于指针操作不当而带来的内存错误

  简单易用,功能强大。

引用在函数返回值中的使用。

  

/*  编译环境
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
*/
#include <stdio.h>
int& func1(void)
{
int a=;
return a;
}
//相当于c 语言中的
/*
int * func1(void)
{
int a= 5;
return &a;
}
*/
int& func2(void)
{
static int b = ;
return b;
}
/*
int * func2(void)
{
static b = 10;
return &b;
}
*/
int main(int argc, char *argv[])
{
int &a = func1();
int &b = func2();
printf("Begin...\n");
//运行将会产生段错误
//产生段错误的原因是,因为 在func1 中a 是一个局部变量,在执行完成后将会被销毁
//a 指向一个被销毁的空间,自然会出错。而如果使用static 来修饰将不会出现段错误。
//因为使用static 会将变量声明为一个全局的变量。
printf("a = %d\tb = %d\n",a,b); //打印结果 a = 未知数 b = 10
printf("End...\n");
return ;
}

  运行结果:

Begin...
Segmentation fault (core dumped)

  在int a 替换为  static int a 后运行结果:(能够正常运行)

Begin...
a = b =
End...

小结:

  引用作为变量别名存在目的是为了代替指针。

  cons引用可以让变量获得只读属性。

  引用的最终实现还是指针。

  引用可以尽可能的避开内存错误。

  

  

C++ 引用深入理解的更多相关文章

  1. 【转】C++ 11 右值引用的理解

    右值引用的目的之一,是为了C++中一个比较影响性能的问题:拷贝临时对象,例如,在 int foo(){ ... } int x; x = foo(); 中,在第三句中,发生了以下的事情: 1.销毁 x ...

  2. Java中“指针”的解释以及对“引用”的理解

    Java中"指针"的解释以及对"引用"的理解 初学Java面对对象编程,对于一些概念还真的有点难以理解,主要是因为不由自主的联系到以前学过的C语言知识,时不时的 ...

  3. 《深入理解计算机系统》第7章:重定位PC相对引用的理解

    在第七章<链接>中的静态链接有对符号进行重定位PC相对引用的处理,书上对应的还有公式,但不是很好理解.现做实验对公式进行理解(公式内容如有兴趣可以参考原文)

  4. 对指针和引用的理解(c++)

    1.指针 typedef说明一种新类型名,来代替已有类型名. a.案例:typedef char* String_t和#define String_d char *这两句在使用上的区别? 1)前者声明 ...

  5. Java中对象和引用的理解

    偶然想起Java中对象和引用的基本概念,为了加深下对此的理解和认识,特地整理一下相关的知识点,通过具体实例从两者的概念和区别两方面去更形象的认识理解,再去记忆. 一.对象和引用的概念: 在Java中万 ...

  6. Spring的3级缓存和循环引用的理解

    此处是我自己的一个理解,防止以后忘记,如若那个地方理解不对,欢迎指出. 一.背景 在我们写代码的过程中一般会使用 @Autowired 来注入另外的一个对象,但有些时候发生了 循环依赖,但是我们的代码 ...

  7. python 05 关于对python中引用的理解

    数据的在内存中的地址就是数据的引用. 如果两个变量为同一个引用,那么这两个变量对应的数据一定相同: 如果两个变量对应的数据相同,引用不一定相同. 通过id(数据)可以查看数据对应的地址,修改变量的值, ...

  8. Office EXCEL 的绝对引用和相对引用如何理解

    比如C1 = A1+B1,则我把C1的单元格往下拖拉的时候,C2会自动等于A2+B2,C3会自动等于A3+B3,而如果让G1 = $E$1+$F$1,则把G1单元格往下拖拉的时候,G2G3单元格都不会 ...

  9. java import跨包引用类理解

    当前类要用其他类时,import具体包路径+.+具体的类 import引入的是被引用类的class文件,所以当我们build path第三方jar包时, 要用他们的类,要把jar包add to bui ...

随机推荐

  1. AtCoder4351 Median of Medians 二分, 树状数组

    题目大意 定义一个从小到大的数列的中位数为第 $ \frac{n}{2}+1 $ 项.求一个序列的所有连续子序列的中位数的中位数. $ (n \leqslant 100000)$ 问题分析 由于\(n ...

  2. getFieldDecorator用法(一)——登录表单

    之前使用antd的ui表单,却没发现这么好用的用法,推荐给大家 import React from "react"; import { Card, Form, Input, But ...

  3. char和vachar的字段长度怎么影响数据库的性能的

    1.限制规则 字段的限制在字段定义的时候有以下规则: a)                  存储限制 varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度 ...

  4. mongo注解详解

    1.@Entity如果你想通过Morphia把你的对象保存到Mongo中,你首先要做的是使用@Entity注解你的类:@Entity(value="comm_user_favorite_co ...

  5. ES6 正则的扩展(待细读)

    1.RegExp构造函数 在 ES5 中,RegExp构造函数的参数有两种情况. a.参数是字符串,这时第二个参数表示正则表达式的修饰符(flag) var regex = new RegExp('x ...

  6. vue组件化之模板优化及注册组件语法糖

    vue组件化之模板优化及注册组件语法糖 vue组件化 模板 优化  在 https://www.cnblogs.com/singledogpro/p/12054895.html 这里我们对vue.js ...

  7. Mac 安装 Novicat

    https://blog.csdn.net/jor_ivy/article/details/81323199 详细见这篇文章

  8. 写python获取android设备的GPS及姿态信息

    在android上,我们可以使用QPython来编写.执行Python脚本.它对很多android 系统函数进行了方便的封装,使用QPython编写功能简单的小程序异常方便. 这个示例是我之前用来读取 ...

  9. python-静态方法和类方法及其使用场景

    静态方法和类方法 静态方法 我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息.实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个"三角形"类,通 ...

  10. Python基本语法_运算符详解

    目录 目录 前言 软件环境 身份运算符 算术运算符 比较运算符 位移运算符 自变运算符 位运算符 逻辑运算符 成员关系运算符 Python真值表 最后 前言 在前面的博文介绍了Python的数据结构之 ...