关于c++的引用

四区

首先,我们要先了解C++中的内存四区即:代码区、全局区、栈区、堆区。

  1. 代码区:存放函数体的二进制代码,由操作系统进行管理。

  1. 全局区:存放全局变量和静态变量以及常量。

  1. 栈区:由编译器自动分配和释放存放函数的参数值,局部变量等。

  1. 堆区:由程序员分配和释放,如果程序员不释放,程序结束后由操作系统回收。

前面两个区是属于程序运行前的,后两个是在程序运行后才有的。

全局区

主要存放全局变量和static修饰的变量,还有常量,常量有分为”字符串常量“和”const修饰的全局变量“,注意:const修饰的局部变量不在全局区中,而static修饰的变量都在全局区中。

栈区

关于栈区要注意,不能返回局部变量的地址。

int *func()
{
    int a = 10;
    return &a;
 } 

因为局部变量是存放在栈区,在函数被执行完后就会被销毁

堆区

接下来我们将认识

一个新的关键字new(可以与C中的malloc类比),利用new我们可以将数据开辟到堆区。new会返回数据存放的地址

int *func()
{
    int *a = new int(10);
    return a;
 } 

int *a = new int(10); //指针本质上其实是局部变量,放在栈区,但是其保存的数据放在堆区。

int *func()
{
    int p = 10;
    int *a = &p;
    return a;
 } 

如上,此时数据存放在栈区,函数结束后会被释放。

new关键字

现在我们深入了解一下关键字new

堆区的数据由程序员开辟,当然也由程序员释放

即用delete关键字释放。

当然,我们也可以在堆区开辟数组

void arr()
{
   int *arr = new int[10]//开辟一个10个整型数据的数组
//释放方法
   delete [] arr;
}

方法总结:

存放一个数据:

int *p = new int(10);

删除一个数据:

delete p;

存放一个数组:

int *arr = new int[10];

删除一个数组:

delete [] arr;

引用

实际上引用就是一个指针常量。

下面我们就先来熟悉一下指针常量和常量指针。

指针常量

这一概念我们通过代码进行认识

    //1.const修饰指针    常量指针 
    int a = 10;
    int b = 10;
    const int *p = &a;
   // *p = b;不可以
    *p = &b;

在常量指针下指针的指向可以改,但是指针指向的值不可以改,例如上述代码,我们是无法修改p指针所指向的值的,而我们可以将指针p指向b的地址。注意:就算指针p指向了b的地址也是无法对b的值进行修改的

常量指针

    //2.const修饰常量
    int *const p2 = &a;//指针的指向不可以改 
    //p = &b
    *p2 = 20; 

而常量指针则相反,我们无法修改常量指针的指向,但我们可以修改其指向的值。

还有一种是两者的结合。

    //3.const修饰指针和常量 
    const int * const p3 = &a;//两者都不可以改 

这种我们两者都无法修改。

引用的使用方法

引用可看作给变量取的别名

int a;
int &b = a;

如上,b就相当于a的另一个名字

示例:

#intclude<iostream>
using namespace std;
int main()
{
    int a = 10;
    int &ref = a; 
    cout << "a=" << a <<endl;
    cout << "ref=" << ref <<endl;
    ref = 100;
    cout << "a=" << a <<endl;
    cout << "ref=" << ref <<endl;
    system("pause");
    reutrn 0;
 } 

引用的注意事项

  1. 引用必须初始化。

  1. 引用在初始化后,就不可改变。

我们不可以直接int &b; 引用的时候必须初始化。

int main(){
   //int &b;(错误)
   int a=10;
   int &b = a;
   int c = 20;
   b = c;//这个含义并不是让b成为c的别名,而是赋值操作
}

引用做函数参数

函数传参时,我们可以利用引用实现指针修改实参的效果

示例:

void Myswap2(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void Myswap3(int &a,int &b)
{
    int temp = a;
    a = b;
    b = temp;
}

两者的效果是相同的,使用引用我们可以简化指针传参的操作。

引用做函数的返回值

#include<iostream>
using namespace std;
//引用做函数的返回值
int &test01()
{
    int a = 10;
    return a;
 } 
int main()
{
    int &ref = test01();
    cout<<ref<<endl;
    cout<<ref<<endl;
    system("pause");
    return 0;
}

上面的代码是错误的,因为a是局部变量,当函数被执行完了就会被编译器释放。那我们要如何实现呢?

#include<iostream>
using namespace std;
//引用做函数的返回值
int &test01()
{
    static int a = 10;
    return a;
 } 
int main()
{
    int &ref = test01();
    cout<<ref<<endl;
    cout<<ref<<endl;
    system("pause");
    return 0;
}

我们将a改为静态变量,这样a就存在全局区,由系统进行释放操作,只有程序运行完了才会被释放。

还有一个补充的点:函数的调用可以作为左值。

#include<iostream>
using namespace std;
//引用做函数的返回值
int &test01()
{
    static int a = 10;
    return a;
 } 
int main()
{
    int &ref = test01();
    cout<<ref<<endl;
    cout<<ref<<endl;
    test01() = 100;//函数的调用可以作为左值。
    cout<<ref<<endl;
    cout<<ref<<endl;
    system("pause");
    return 0;
}

引用的本质

引用的本质在C++相当于一个指针常量

#include<iostream>
using namespace std;
int main()
{
    int a = 10;
    int &b = a;//相当于 int const *b = &a;
    b = 100;//相当于 *b = 100;
}

ok,完工!!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值