C#内存数据存放问题------堆区、栈区和静态存储区

本篇文章将以最简单易懂的方式介绍数据在堆区栈区和静态存储区中存放问题

一、什么是堆区和栈区

栈区 :先进后出,后进先出

堆区 :数据可以任意出入

区别:

栈空间比较小,但是读取速度快

堆空间比较大,但是读取速度慢

这也决定了数据在堆区和栈区存储类型、方式的不同

二、值类型与引用类型

在弄懂数据存储问题之前,明白值类型与引用类型也是必不可少的;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_14,color_FFFFFF,t_70,g_se,x_16

1、值类型存储问题

            int c1 = 5;
            int c2 = c1;
            Console.WriteLine(c1);
            Console.WriteLine(c2);

            c1 = 6;
            Console.WriteLine(c1);
            Console.WriteLine(c2);

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

在这串代码中,首先定义一个整型变量(值类型)对象c1,并将c1的值赋给c2,输出结果为5,5;

后改变c1的值为6,输出结果为什么c2还是等于5呢?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 定义的值类型c1,c2的值直接存放在栈区,并且同时享用一块内存区域

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

当c1被重新赋值后,系统会在栈区重新申请一块内存区域存放c1,此时c1,c2内存地址也相应的发生改变 

2、引用类型存储问题

            string c1 = "看完这篇文章";
            string c2 = c1;
            Console.WriteLine(c1);
            Console.WriteLine(c2);

            c1 = "肯定要三连!";
            Console.WriteLine(c1);
            Console.WriteLine(c2);
            Console.ReadKey();

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

这里定义了一个string引用类型的变量c1 ,并将c1的值赋给c2,看起来和上述的值类型存储差不多,但其实引用类型和值类型存放的位置不同

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

与值类型不同的,变量c1与c2 会在栈区和堆区同时存放数据,栈区存放16进制地址指向存放在静态存储区的常量

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 当c1被重新赋值后,系统会在静态存储区重新申请一块内存区域存放c1的数据,此时c1,c2所指向的内存地址也相应的发生改变 

3、对象引用的改变

namespace ConsoleApp1
{
    class Question
    {
        string c1 ;
        string c2 ;
        public Question(string c1,string c2)
        {
            this.c1 = c1;
            this.c2 = c2;
        }
        public void show()
        {
            Console.WriteLine(c1);
            Console.WriteLine(c2);
        }
        public void Modify()
        {
            c1 = "没有看完这个视频";
            c2 = "也要点赞!";
        }
    }
}

            Question obj1 = new Question("看完这篇文章","肯定要点赞");
            Question obj2 = obj1;
            obj1.show();
            obj2.show();

            obj1.Modify();
            obj1.show();
            obj2.show();

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 从运行结果可以看出,这个例子与上述两个案例都不一样,当c1发生改变时,c2的值也随之发生改变

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGFyeUNvZGluZw==,size_20,color_FFFFFF,t_70,g_se,x_16

在对象的引用中,c1和c2共享一片内存单元,当c1调用Modify函数更改数据时 ,c1,c2也指向相同的一块地址区域

猜你喜欢

转载自blog.csdn.net/weixin_53346875/article/details/123633005
今日推荐