C++ 中你不知道的引用

在这里插入图片描述
#千锋物联网逆战#
我们总以为,是生活欠我们一个“满意”,其实是我们欠生活一个“努力”。

1、给已有变量取个别名

int num = 10;
int &a = num;//此处 &不是取地址 而是标明 a是引用变量(a 是 num的别名)

在这里插入图片描述

注意:

1、引用必须初始化
2、引用一旦初始化 就不能再次修改别名

int num = 10;
int &a = num;

int data = 20;
a = data;//不是data别名为a  而是将data值赋值a(num)

2、引用 给数组 取个别名

2.1、方法1:

void test02()
{
    int arr[5] = {10,20,30,40,50};
    //需求:给arr起个别名
    int (&my_arr)[5] = arr;//my_arr就是数组arr的别名

    int i=0;
    for(i=0;i<5;i++)
    {
        cout<<my_arr[i]<<" ";
    }
    cout<<endl;
}

2.2、配合typedef

void test03()
{
    int arr[5] = {10,20,30,40,50};
    //1、用typedef 给数组类型 取个别名
    //TYPE_ARR就是一个数组类型(有5个元素 每个元素位int)
    typedef int TYPE_ARR[5];

    //myArr就是数组arr的别名
    TYPE_ARR &myArr=arr;

    int i=0;
    for(i=0;i<5;i++)
    {
        cout<<myArr[i]<<" ";
    }
    cout<<endl;
}

3、引用作为函数的参数

void my_swap1(int a,int b)
{
    int tmp = a;
    a = b;
    b=tmp;
}
void my_swap2(int *a,int *b)//a=&data1,b =data2;
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

void my_swap3(int &a, int &b)//a=data1,b=data2
{
    int tmp = a;
    a = b;
    b= tmp;
}
void test04()
{
    int data1 = 10,data2=20;
    cout<<"data1 = "<<data1<<", data2 = "<<data2<<endl;
    //my_swap1(data1,data2);//交换失败
    //my_swap2(&data1,&data2);//交换成功
    my_swap3(data1,data2);//交换成功(推荐)
    cout<<"data1 = "<<data1<<", data2 = "<<data2<<endl;
}

4、引用作为函数的返回值

给函数的返回值 取个别名

//引用作为函数的返回值类型
int& my_data(void)
{
    int num = 100;
    return num;//err 函数返回啥变量 引用就是该变量的别名
    //函数的返回值是引用时  不要返回局部变量
}
int& my_data1(void)
{
    static int num = 200;
    return num;//ok
}
void test05()
{
    //ret是别名 ret是num的别名
    int &ret = my_data();
    //cout<<"ret = "<<ret<<endl;//非法访问内存

    int &ret1 = my_data1();//ret1是num的别名
    cout<<"ret = "<<ret1<<endl;
}

当函数返回值作为左值 那么函数的返回值类型必须是引用。

int& my_data(void)
{
	static int num = 10;
	cout<<"num ="<<num<<endl;
	return num;
}
void test06()
{
    my_data() = 2000;
    my_data();
}

运行结果:
在这里插入图片描述

5、引用的本质(了解)

引用的本质在c++内部实现是一个指针常量. Type& ref = val; // Type* const ref = &val;
c++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户不可见

int data = 10;
int &a = data;//a就是data的别名
//编译器内存转换:int * const a = &data;

a=100;//等价于data=100
//*a = 100;//*a == data

6、指针的引用(了解)

#include<stdlib.h>
#include<string.h>
void my_str1(char **p_str)//p_str = &str
{
    //*p_str == *&str == str
    *p_str = (char *)calloc(1,32);
    strcpy(*p_str, "hello world");

    return;
}
void my_str2(char* &my_str)//char* &my_str = str;my_str等价str
{
    my_str = (char *)calloc(1,32);
    strcpy(my_str, "hello world");
    return;
}
void test07()
{
    char *str = NULL;
    //需求:封装一个函数 从堆区 给str申请一个空间 并赋值为"hello world"
    //my_str1(&str);
    my_str2(str);
    cout<<"str = "<<str<<endl;
    free(str);
}

7、常引用

7.1、引导出常引用(重要)

typedef struct
{
    int num;
    char name[32];
}STU;
void myPrintSTU1(STU tmp)//普通结构体变量作为形参 开销太大
{
    cout<<sizeof(tmp)<<endl;
    cout<<"学号:"<<tmp.num<<", 姓名:"<<tmp.name<<endl;
}
void myPrintSTU2(const STU &tmp)//STU &tmp=lucy;tmp是lucy的别名 tmp没有开辟独立空间
{
    //tmp.num = 2000;//err 因为tmp为常引用
    cout<<"学号:"<<tmp.num<<", 姓名:"<<tmp.name<<endl;
}
void test08()
{
    STU lucy = {100,"lucy"};

    //需求:定义一个函数 遍历lucy成员(读操作)
    myPrintSTU2(lucy);
}

7.2、常量的引用(了解)

void test09()
{
    //给常量10取个别名 叫num
    //int &针对的是int ,10是const int类型
    //const int 针对的是const int, 10是const int类型
    const int &num = 10;

    cout<<"num = "<<num<<endl;//10
}
发布了52 篇原创文章 · 获赞 42 · 访问量 4960

猜你喜欢

转载自blog.csdn.net/weixin_43288201/article/details/104905841