1、变量名

变量名实质上是一段连续存储空间的别名,是一个标号(门牌号);

通过变量来申请并命名内存空间;

通过变量的名字可以使用内存空间。

2、引用的概念

变量名,本身是一段内存的引用,即别名(alias)。引用可以看作一个已定义变量的别名。

引用的语法:Type & name = var;

用法如下:

#include <iostream>
using namespace std; int main(void)
{
int a = ;//C编译器分配4个字节内存,a内存空间的别名
int &b = a;//b就是a的别名 a = ;
{
int *p = &a;
*p = ;
cout << a << endl;//
}
b = ;
cout << "a=" << a << ",b=" << b << endl;//a=14,b=14
return ;
}

引入:

变量名,实际上是一段连续存储空间的别名,是一个标号(门牌号)。

程序中通过变量来申请并命名内存空间,通过变量的名字可以使用存储空间。

问题:对一段连续的内存空间只能取一个别名吗?

第一,引用的概念

(1)在C++中新增加了引用的概念;

(2)引用可以看作一个已定义变量的别名

(3)引用的语法:Type& name = var;

(4)引用做函数参数(引用作为函数参数声明时不进行初始化)

比如,有这么一个人,我们称作“姥姥”,也有人称呼是“外婆”,有人问你你姥姥是谁?或者问你你外婆是谁?我们知道这两个称呼指的是同一个人,你妈给了你姥姥一千块钱,你姥姥多了一千块钱,那么你外婆也就多了一千块钱,你外婆又给了你五百块钱压岁钱,那你姥姥也就是少了五百块钱。姥姥 == 外婆,通过修改外婆持有的资产数额,就修改了姥姥持有的资产数额!

运行以下程序,变量a的别名定义为b,我们修改a的值就修改了b的值,修改b的值就修改了a的值。

第二,通过引用交换两个变量的值

我们知道这个程序是无法实现交换两个数值的,如果想交换两个数值,按照以前的办法就是使用指针,这里不多说。

我们学习了引用之后可以通过引用来实现交换两个变量的值。

如下程序,x、y是实参,a、b是形参,将实参x、y赋值给形参a、b,a、b就是x、和y的别名,改a、b就是把x、y的数值改了。

3、规则

(1)引用没用定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故类型与原类型保持一致,且不分配内存,与被引用的变量有相同的地址。

(2)声明的时候必须初始化,一经声明,不可更改。

(3)可对引用,再次引用,多次引用的结果是某一变量具有多个别名。

(4)&符号前有数据类型时是引用,其它皆为地址。

#include <iostream>
using namespace std; int main(void)
{
int a,b;
int &r = a;
int &r = b;//error,不可更改原有的引用关系——规则(2)
float &rr = b;//error,引用类型不匹配——规则(1)
cout <<"&r="<< &r << ",&a=" << &a << endl;//变量与引用具有相同的地址——规则(1)
int &ra = r;//可对引用再次引用,表示a变量有两个别名,分别是r和ra——规则(3) return ;
}

4、引用作为函数参数

普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化

#include <iostream>
using namespace std; struct Teacher
{
char name[];
int age;
};
void printfT(Teacher *pT)
{
cout << pT->age << endl;
} void printfT2(Teacher &pT)//pT是t1的别名,相当于修改了t1
{
pT.age = ;
cout << pT.age << endl;
} void printfT3(Teacher pT)//pT和t1是两个不同的变量
{
cout << pT.age << endl;
pT.age = ;//只会修改pT变量,不会修改t1变量
} int main(void)
{
Teacher t1;
t1.age = ; printfT(&t1);// printfT2(t1);//33,pT是t1的别名
printf("t1.age:%d\n", t1.age);// printfT3(t1);//33,pT是形参,t1拷贝一份数据给pT
printf("t1.age:%d\n", t1.age);// return ;
}

5、引用的意义

(1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针;

(2)引用相对于指针来说具有更好的可读性和实用性。

c++中引入引用后,可以用引用解决的问题避免用指针来解决。

#include <iostream>
using namespace std; struct student
{
int age;
char name[];
};
void swap1(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
} void swap2(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
} void printS1(struct student s)//子拷贝方式:student s=s1;结构体整个值拷贝的动作
{
cout << s.age << " " << s.name << endl;
} void printS2(struct student *sp)//指针方式
{
cout << sp->age << " " << sp->name << endl;
} void printS3(struct student &sp)//引用方式:student &s=s1;
{
cout << sp.age << " " << sp.name << endl;
} int main(void)
{
int a = ;
int b = ;
swap1(&a, &b);
cout << "a=" << a << ",b=" << b << endl;//a=20,b=10 int c = ;
int d = ;
swap2(c, d);
cout << "c=" << c << ",d=" << d << endl;//c=200,d=100 student s1 = { ,"zhang3" };
printS1(s1);//10 zhang3
printS2(&s1);//10 zhang3
printS3(s1);//10 zhang3
return ;
}

05C++引用的更多相关文章

  1. 【.net 深呼吸】序列化中的“引用保留”

    假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ...

  2. CSS 选择器及各样式引用方式

    Css :层叠样式表 (Cascading Style Sheets),定义了如何显示HTML元素. 目录 1. 选择器的分类:介绍ID.class.元素名称.符合.层次.伪类.属性选择器. 2. 样 ...

  3. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  4. C++中的引用

    一,C++中引用的基础知识 1.引用的基本概念 1.所谓的引用其实就是对变量起“别名”.引用和变量对应得是相同的内存,修改引用的值,变量的值也会改变,和指针类似. 2.引用在定义的时候必须要初始化,初 ...

  5. Java 为值传递而不是引用传递

    ——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...

  6. EC笔记:第4部分:21、必须返回对象时,别返回引用

    使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ...

  7. EC笔记:第4部分:20、传递引用代替传值

    考虑以下场景: #include <iostream> #include <string> using namespace std; struct Person { strin ...

  8. 编译器开发系列--Ocelot语言2.变量引用的消解

    "变量引用的消解"是指确定具体指向哪个变量.例如变量"i"可能是全局变量i,也可能是静态变量i,还可能是局部变量i.通过这个过程来消除这样的不确定性,确定所引用 ...

  9. C++右值引用浅析

    一直想试着把自己理解和学习到的右值引用相关的技术细节整理并分享出来,希望能够对感兴趣的朋友提供帮助. 右值引用是C++11标准中新增的一个特性.右值引用允许程序员可以忽略逻辑上不需要的拷贝:而且还可以 ...

随机推荐

  1. Android简易项目--傻瓜式阿拉伯语输入法(Dummy Arabic Input)

    一.应用名称 Android简易项目--傻瓜式阿拉伯语输入法(Dummy Arabic Input) 二.应用图标 三.应用说明 现在通行的阿拉伯语键盘布局并无规律可循,阿拉伯语使用者需要花费较多时间 ...

  2. Linux系统管理常用命令用法总结(2)

    1.free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等. 语法:free [-bkmotV][-s <间隔秒数>] 参数说明: - ...

  3. IE浏览器兼容的处理方式之一,使用特殊的注释 <!--[if IE]> ....<![endif]-->

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. JSONP解决跨域问题,什么是JSONP(转)

    原文链接:https://www.cnblogs.com/xinxingyu/p/6075881.html 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的 ...

  5. Delphi 10.3实现Android App的动态权限申请

    Delphi 10.3 RIO发布近两个月,针对Google Play的要求,完美实现了对Android 8的支持,即对Android API Level 26的支持.这支持当中,最主要的得算是动态申 ...

  6. 内存直读技术DMA

    DMA(Direct Memory Access) DMA(Direct Memory Access)即直接存储器存取,是一种快速传送数据的机制. 工作原理 DMA是指外部设备不通过CPU而直接与系统 ...

  7. HDU 1808 Halloween treats(抽屉原理)

    题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=1808 Problem Description Every year there is the same ...

  8. Github笔记(1)

    学习目的: 借助GitHub托管项目代码 GitHub官方介绍: 中文:http://www.cnblogs.com/twtp/articles/5264073.html 英文:https://gui ...

  9. error:1407742 E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

    /********************************************************************************* * error:1407742 E ...

  10. 从boost到Adaboost再到GBRT-GBDT-MART

    本文是要配合<统计学习方法>才能看懂的,因为中间有些符号和定义是直接使用书本中的 先弄明白以下三个公式: 1)Boost(提升法)=加法模型(即基函数的线性组合)+前向分步算法+损失函数 ...