05C++引用

1、变量名

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

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

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

2、引用的概念

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

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

用法如下:

#include <iostream>
using namespace std;

int main(void)
{
    int a = 10;//C编译器分配4个字节内存,a内存空间的别名
    int &b = a;//b就是a的别名

    a = 11;
    {
        int *p = &a;
        *p = 12;
        cout << a << endl;//12
    }
    b = 14;
    cout << "a=" << a << ",b=" << b << endl;//a=14,b=14
    return 0;
}

引入:

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

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

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

第一,引用的概念

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

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

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

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

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

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

 

E:\Users\lsj\Desktop\1.png

 

E:\Users\lsj\Desktop\2.png

 

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

 

E:\Users\lsj\Desktop\3.png

 

E:\Users\lsj\Desktop\4.png

 

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

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

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

E:\Users\lsj\Desktop\5.pngE:\Users\lsj\Desktop\6.png

 

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 0;
}

4、引用作为函数参数

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

#include <iostream>
using namespace std;

struct Teacher
{
    char name[64];
    int age;
};
void printfT(Teacher *pT)
{
    cout << pT->age << endl;
}

void printfT2(Teacher &pT)//pT是t1的别名,相当于修改了t1
{
    pT.age = 33;
    cout << pT.age << endl;
}

void printfT3(Teacher pT)//pT和t1是两个不同的变量
{
    cout << pT.age << endl;
    pT.age = 45;//只会修改pT变量,不会修改t1变量
}

int main(void)
{
    Teacher t1;
    t1.age = 35;

    printfT(&t1);//35

    printfT2(t1);//33,pT是t1的别名
    printf("t1.age:%d\n", t1.age);//33

    printfT3(t1);//33,pT是形参,t1拷贝一份数据给pT
    printf("t1.age:%d\n", t1.age);//33

    return 0;
}

5、引用的意义

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

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

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

#include <iostream>
using namespace std;

struct student
{
    int age;
    char name[64];
};
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 = 10;
    int b = 20;
    swap1(&a, &b);
    cout << "a=" << a << ",b=" << b << endl;//a=20,b=10

    int c = 100;
    int d = 200;
    swap2(c, d);
    cout << "c=" << c << ",d=" << d << endl;//c=200,d=100

    student s1 = { 10,"zhang3" };
    printS1(s1);//10 zhang3
    printS2(&s1);//10 zhang3
    printS3(s1);//10 zhang3
    return 0;
}

 

转载于:https://www.cnblogs.com/xinmomoyan/p/10606732.html

_KTHREAD +0x000 Header : _DISPATCHER_HEADER +0x010 CycleTime : Uint8B +0x018 HighCycleTime : Uint4B +0x020 QuantumTarget : Uint8B +0x028 InitialStack : Ptr32 Void +0x02c StackLimit : Ptr32 Void +0x030 KernelStack : Ptr32 Void +0x034 ThreadLock : Uint4B +0x038 WaitRegister : _KWAIT_STATUS_REGISTER +0x039 Running : UChar +0x03a Alerted : [2] UChar +0x03c KernelStackResident : Pos 0, 1 Bit +0x03c ReadyTransition : Pos 1, 1 Bit +0x03c ProcessReadyQueue : Pos 2, 1 Bit +0x03c WaitNext : Pos 3, 1 Bit +0x03c SystemAffinityActive : Pos 4, 1 Bit +0x03c Alertable : Pos 5, 1 Bit +0x03c GdiFlushActive : Pos 6, 1 Bit +0x03c UserStackWalkActive : Pos 7, 1 Bit +0x03c ApcInterruptRequest : Pos 8, 1 Bit +0x03c ForceDeferSchedule : Pos 9, 1 Bit +0x03c QuantumEndMigrate : Pos 10, 1 Bit +0x03c UmsDirectedSwitchEnable : Pos 11, 1 Bit +0x03c TimerActive : Pos 12, 1 Bit +0x03c SystemThread : Pos 13, 1 Bit +0x03c Reserved : Pos 14, 18 Bits +0x03c MiscFlags : Int4B +0x040 ApcState : _KAPC_STATE +0x040 ApcStateFill : [23] UChar +0x057 Priority : Char +0x058 NextProcessor : Uint4B +0x05c DeferredProcessor : Uint4B +0x060 ApcQueueLock : Uint4B +0x064 ContextSwitches : Uint4B +0x068 State : UChar +0x069 NpxState : Char +0x06a WaitIrql : UChar +0x06b WaitMode : Char +0x06c WaitStatus : Int4B +0x070 WaitBlockList : Ptr32 _KWAIT_BLOCK +0x074 WaitListEntry : _LIST_ENTRY +0x074 SwapListEntry : _SINGLE_LIST_ENTRY +0x07c Queue : Ptr32 _KQUEUE +0x080 WaitTime : Uint4B +0x084 KernelApcDisable : Int2B +0x086 SpecialApcDisable : Int2B +0x084 CombinedApcDisable : Uint4B +0x088 Teb : Ptr32 Void +0x090 Timer : _KTIMER +0x0b8 AutoAlignmen
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值