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. linux下Mysql多实例实现

    什么是MySQL多实例 MySQL多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过不同的socket监听不同的服务端口来提供各自的服务:: My ...

  2. fftshift函数详解

    reference: https://ww2.mathworks.cn/help/matlab/ref/fftshift.html 一.实信号情况 因为实信号以fs为采样速率的信号在 fs/2处混叠, ...

  3. DevExpress v18.1新版亮点——Analytics Dashboard篇(二)

    用户界面套包DevExpress v18.1日前正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress Analytics Dashboard v18.1 的新功能,快 ...

  4. spoon 更新数据

    一个小需求,被要求使用spoon 来同步数据 主要流程为: 1.查询A库未同步数据 id 2.根据步骤1查到的id,作为条件更新B库数据 3.更新B库数据成功则更改库A中的数据状态为已同步. 4.添加 ...

  5. 20165326 java第五周学习笔记

    第五周学习笔记 ch7 内部类(&外嵌类) 内部类的类体不可以声明类变量和方法 内部类如同类的变量或方法 内部类和外嵌类在编译时生成两个class文件 匿名类 某个类的一个子类没有明显的用类声 ...

  6. VC 任务栏图标闪烁

    像QQ来消息时的,图标闪烁效果 将如下代码添加到Timer响应函数中 ) {// 任务栏图标闪烁 if (this != GetForegroundWindow()) { //// this-> ...

  7. Delphi 10.2.3 新增的TMimeTypes类

    Delphi 10.2.3 新增的TMimeTypes类,利用url中的文件扩展名,可以轻松得到url需要返回的HTTP content-type类型,可以参考这里,现在查看AddDefTypes方法 ...

  8. 【Python】利用正则解析xml练习题

    { "date": "18-03-29 06:04:47", "data": { "deviceType": 1, &q ...

  9. 从输入URL到页面加载发生了什么?

    总体来说分为以下几个过程: DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 具体内容点这里

  10. str 类型

    1.capitalize():首字母大写 2.center(size,fillwith): 3.count(sub,start,end):计算子序列的个数 4.decode() 5.encode() ...