四、引用

一、引用的基本语法

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

// 1. 引用的基本语法  type &别名 = 原名
void test01()
{
    int a = 10;
    int &b = a;
    b = 20;
    cout << "a = " << a << endl;   // a = 20
    cout << "b = " << b << endl;   // b = 20
}

二、引用必须初始化

void test02()
{
    // int &a; // 报错, 引用必须初始化
    int b = 10;
    int &c = b; 
    int d = 20;
    // c = d; // 不会报错, 这里是赋值操作,不再是引用a了,所以引用之后不能重新引用,输出的结果是a,b,c == 20
}

三、对数组的引用

void test03()
{
    int arr[10];
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        arr[i] = i;
    }
    // 给数组起别名
    // 方式一
    int(&pArr)[10] = arr;  // 10 不能省略
    for (i = 0; i < 10; i++)
    {
        cout << pArr[i] << "  ";  // 0 1 2 3 4 5 6 7 8 9
    }
    cout << endl;

    // 方式二
    typedef int ARRAYREF[10]; // 一个具有是个元素的 int 类型的数组
    ARRAYREF &pArr2 = arr;
    for (i = 0; i < 10; i++)
    {
        cout << pArr2[i] << "  ";  // 0 1 2 3 4 5 6 7 8 9
    }
}

四、函数参数的引用

4.1 值传递与地址传递

// 值传递
void test04(int x, int y)
{
    int tmp = x;
    x = y;
    y = tmp;
}

// 地址传递
void test05(int* x, int* y)
{
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}

int main()
{
    int a = 10;
    int b = 20;
    test04(a, b);  // 值传递
    cout << "a = " << a << endl; // a = 10
    cout << "b = " << b << endl; // b = 20
    test05(&a, &b);  // 地址传递
    cout << "a = " << a << endl; // a = 20
    cout << "b = " << b << endl; // b = 10
    return EXIT_SUCCESS;              
}

4.2 引用传递(类似于地址传递)

void test06(int &x, int &y)
{
    int tmp;
    tmp = x;
    x = y;
    y = tmp;
}

int main()
{
    int a = 10;
    int b = 20;
    test06(a, b);
    cout << "a = " << a << endl; // a = 20
    cout << "b = " << b << endl; // b = 10
    return EXIT_SUCCESS;              
}

五、函数返回值引用

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

int& doWork() 
{
    int a = 10;
    return a;
}

int& doWork2()
{
    static int b = 10;
    return b;
}

void test()
{
    int &ret1 = doWork();   // 引用不能引用局部变量的引用
    int &ret2 = doWork2();  // 函数的返回值是引用,那么函数的调用可以作为左值
    cout << "ret1 = " << ret1 << endl;  // ret1  = 10   局部变量调用之后就被销毁了,这次是对的是编译器的优化所致,后面就不会对了
    cout << "ret1 = " << ret1 << endl;  // 乱码
    cout << "ret1 = " << ret1 << endl;  // 乱码
    cout << "ret1 = " << ret1 << endl;  // 乱码
    cout << "ret2 = " << ret2 << endl;  // ret2 = 10
    cout << "ret2 = " << ret2 << endl;  // ret2 = 10
    cout << "ret2 = " << ret2 << endl;  // ret2 = 10
}

int main()
{
    test();

    return EXIT_SUCCESS;              
}

 

六、引用的注意事项

1. 必须初始化
2. 引用之后不能重新引用
3. 引用必须引用一块合法的内存空间 // int &a = 10; 错误
4. 引用不能引用局部变量的引用,如果函数的返回值是引用,那么函数的调用可以作为左值

七、引用的本质

引用的本质在C++内部实现是一个指针常量.
C++编译器在编译过程中使用指针作为引用的内部实现,因此医用所占用的空间大小与指针相同,只是这个过程是编译器内部实现,用户看不见。

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

void testFun(int &ref)
{
    ref = 100;  // ref 是引用, 转换为 *ref = 100
}

int main()
{
    int a = 10;
    int &aRef = a;  // 自动转换为 int *aRef = &a; 这也能说明引用为什么要初始化的原因
    aRef = 20;      // 内部发现 aRef是引用,自动帮我们转换为 *aRef = 20;
    cout << "a = " << a << endl;
    cout << "aRef = " << aRef << endl;
    testFun(a);

    return EXIT_SUCCESS;              
}

八、指针的引用

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

struct Person
{
    int age;
};

void allocMemory(Person ** p)  // **p 是具体的Persoin对象, *p是对象的指针, p是指针的指针
{
    *p = (Person *)malloc(sizeof(Person));
    (*p)->age = 20;
}
void test01()
{
    Person *p = NULL;
    allocMemory(&p);
    cout << "p的年龄 " << p->age << endl; // p的年龄 20
}

// 利用指针引用开辟空间
void allocMemoryByRef(Person* &p)
{
    p = (Person*)malloc(sizeof(Person));
    p->age = 20;
}

void test02()
{
    Person *p = NULL;
    allocMemoryByRef(p);
    cout << "p的年龄 " << p->age << endl; // p的年龄 20
}

int main()
{
    test01();
    test02();
    return EXIT_SUCCESS;              
}

九、常量的引用

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>    
using namespace std; 

void test01()
{
    
    const int &ref = 10; //  加入 const后, 编译器处理方式为 int tmp = 10;  const int &ref = tmp;
    // ref = 20 不能这样改制, 开辟了内存,用指针修改值
    int *p = (int *)&ref;
    *p = 20;
    cout << "ref = " << ref << endl;   // ref = 20
    cout << "*p = " << *p << endl;     // *p = 20
}


int main()
{
    test01();
    return EXIT_SUCCESS;              
}

 

posted on 2022-01-15 17:19  软饭攻城狮  阅读(74)  评论(0编辑  收藏  举报

导航