c++基础学习——内存分区和引用——笔记

内存分区模型
        c++程序在执行时,将内存大方向划分为4个区域
            代码区:存放函数体的二进制代码,由操作系统进行管理的
                存放CPU执行的机器指令
                共享的,频繁的执行,只需要在内存中存放一份即可
                只读的
            全局区:存放全局变量和静态变量及常量
                全局变量和静态变量存放在此
                全局区还包含了常量去,字符串常量和其它常量也存放在此
                该区域的数据在程序结束后由操作系统释放
                
                全局区(在全局区中):
                    全局变量
                    静态变量 static关键字
                    常量
                        字符串常量
                        const修饰的全局变量(全局常量)
                        
                局部变量(不在全局中)
                    const修饰的局部变量(局部常量)
                
            栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
                注意事项:不要返回局部变量的地址,栈区开辟的数据有编译器自动释放 
                新参数据也会放在栈区
                int * func()
                {
                    int a = 10;//局部变量  存放在栈区,栈区的数据在函数执行完后自动释放
                    return &a;
                }

                int main()
                {
                    int * p = func();
                    cout << *p << endl;//第一次可以打印正确的数字,是因为编译器做了保留
                    cout << *p << endl;//第二次这个数据就不在保留了

                    system("puase");
                    return 0;
                }
                
            堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
                在c++中主要利用new在堆区开辟内存
                //利用new关键字  可以将数据开辟到堆区
                //指针  本质也是局部变量  放在栈上,指针保存的数据是放在堆区
                在堆区利用new开辟数组
                //创建10整形数据的数据,在堆区
                int* arr = new int[10];//10代表有10个元素
                
                //堆区的数据  由程序员管理开辟 程序员管理释放
                //释放堆区  关键字 delete
                delete p;//内存已经被释放,再次访问就是非法操作,会报错
    
        内存四区意义
            不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活变成
            
            
引用

    引用基本语法
        数据类型 &别名=原名
    
    引用注意事项
        1、引用必须要初始化
            int&b;//错误的
        2、引用在初始化后,不可以改变

    引用做函数的返回值
        如果函数的返回值是引用,这个函数的调用可以作为左值
        
        
        //不要返回局部变量的引用
        int& test01()
        {
            int a = 10;//局部变量存放在四区中的栈区
            return a;
        }

        //返回静态变量引用
        int& test02()
        {

            static int a = 10;//静态变量,存放在全局区,全局区的数据在程序结束后系统释放
            return a;
        }
        
        int &ref2 = test02();
        cout << "ref2=" << ref2 << endl;
        cout << "ref2=" << ref2 << endl;

        //返回的a的引用,就等于是a=1000
        test02() = 1000;//如果函数的返回值是引用,这个函数的调用可以作为左值

        cout << "ref2=" << ref2 << endl;
        cout << "ref2=" << ref2 << endl;
        
    引用的本质
        int a = 10;
        //自动转换为int* const ref=&a;指针常量是指针指向不可改,也说明为什么引用不可更改
        int& ref = a;
        ref = 20;//内部发现ref是引用,自动帮我们转换为:*ref=20;
        //结论:C++推荐用引用计数,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了
        
    常量引用
        引用必须引用一块合法的内存空间
        加入const之后变为只读,不可以修改
        //int a = 10;
        //加上const之后 编译器将代码修改 int temp = 10; const int & ref=temp;
        //int & ref = 10;//引用必须引用一块合法的内存空间
        //const int & ref = 10;
        
        函数中利用常量引用防止误操作修改实参
        const使用场景:用来修饰形参,防止误操作
    
    
    函数的默认参数
        //如果我们传入数据,就用默认的,如果没有,就用默认的
        //注意事项
        //1、如果某个位置已经有了默认参数,那么从这个位置往后,从左到右都必须有默认值
        //int func2(int a,int b = 10, int c)
        //{
        //
        //}
        //2、如果函数声明有默认参数,函数实现就不能有默认参数
        //声明和实现智只有一个默认参数
    
    
    函数重载
        可以让函数名相同,提高复用性
        //满足条件
            //同一个作用域下
            //函数名相同
            //函数参数类型不同或者个数不同或者顺序不同
        //注意:
            函数的返回值不可以作为函数重载的条件
            当函数重载碰到默认参数,出现二义性,报错,尽量避免这种情况
    

你可能感兴趣的