7.值和引用的区别

7.值类型和引用类型-使用和存储上的区别


7.1 知识点

变量类型复习

  • 无符号整形

    byte by = 1;
    ushort us = 1;
    uint ui = 1;
    ulong ul = 1;
    
  • 有符号整形

    sbyte sby = 1;
    short s = 1;
    int i = 1;
    long l = 1;
    
  • 浮点数

    float f = 1f;
    double d = 1.1;
    decimal de = 1.1m;
    
  • 特殊类型

    bool bo = true;
    char c = 'A';
    string str = "strs";
    
  • 复杂数据类型

    • enum(枚举)
    • 数组(一维,二维,交错)
  • 值类型和引用类型的分类

    • 引用类型: string, 数组, 类(未学习)
    • 值类型: 其它、结构体(未学习)

值和引用的区别

使用上的区别

//值类型
int a = 10;
//引用类型
int[] arr = new int[] { 1, 2, 3, 4 };

//声明了一个b让其等于之前的a
int b = a;
//声明了一个arr2让其等于之前的arr
int[] arr2 = arr;

Console.WriteLine("赋值了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=10
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0]=1, arr2[0]=1

b = 20;
arr2[0] = 5;
Console.WriteLine("修改了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=20
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]); //arr[0] = 5, arr2[0] = 5

总结

值类型在相互赋值时,把内容拷贝给了对方,它变我不变。引用类型的相互赋值是让两者指向同一个值(指向同一内存地址),它变我也变。

为什么有以上区别

值类型和引用类型存储在的内存区域是不同的,存储方式也是不同的:

  • 值类型存储在栈空间:系统分配,自动回收,小而快。
  • 引用类型存储在堆空间:手动申请和释放,大而慢。

New了就是开了新房间,和之前的没有关系,所以arr不会有任何变化。

值类型和引用类型的内存图示




7.2 知识点代码

using System;

namespace Lesson05_值类型和引用类型存储上的区别
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("值类型和引用类型存储上的区别");

            #region 知识点一 变量类型的复习

            //无符号整形
            byte by = 1;
            ushort us = 1;
            uint ui = 1;
            ulong ul = 1;

            //有符号整形
            sbyte sby = 1;
            short s = 1;
            int i = 1;
            long l = 1;

            //浮点数
            float f = 1f;
            double d = 1.1;
            decimal de = 1.1m;

            //特殊类型
            bool bo = true;
            char c = 'A';
            string str = "strs";

            //复杂数据类型
            // enum 枚举 
            // 数组 (一维,二维,交错)

            //可以把以上 学过的 变量类型 分成 值类型和引用类型
            //引用类型: string, 数组, 类(未学习)
            //值类型: 其它、结构体(未学习)
            #endregion

            #region 知识点二 值类型和引用类型的区别

            //1.使用上的区别

            //值类型
            int a = 10;
            //引用类型
            int[] arr = new int[] { 1, 2, 3, 4 };


            //声明了一个b让其等于之前的a
            int b = a;
            //声明了一个arr2让其等于之前的arr
            int[] arr2 = arr;

            Console.WriteLine("赋值了b和arr2[0]之后");
            Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=10
            Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0]=1, arr2[0]=1

            b = 20;
            arr2[0] = 5;
            Console.WriteLine("修改了b和arr2[0]之后");
            Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=20
            Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]); //arr[0] = 5, arr2[0] = 5

            //值类型 在相互赋值时 把内容拷贝给了对方  它变我不变
            //引用类型的相互赋值 是 让两者指向同一个值(指向同一内存地址)  它变我也变


            //2.为什么有以上区别
            //值类型 和 引用类型 存储在的 内存区域 是不同的 存储方式是不同的
            //所以就造成了 他们在使用上的区别

            // 值类型存储在 栈空间  —— 系统分配,自动回收,小而快
            // 引用类型 存储在 堆空间 —— 手动申请和释放,大而慢

            //new 了 就是开了新房间 和之前的 没有什么关系了 所以 arr不会有任何变化
            arr2 = new int[] { 99,3,2,1};
            Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0] = 5, arr2[0] = 99

            #endregion
        }
    }
}

7.3 练习题

int a = 10; int b = a; b = 20; Console.WriteLine(a);请问打印结果为多少?

  • 答: 10

  • 解释: int 是值类型,将 a 的值(10)复制给 b 时,是将实际的值拷贝,而不是引用。因此,b = 20; 不会影响到 a 的值。

int[] a = new int[]{10}; int[] b = a; b[0] = 20; Console.WriteLine(a[0]);请问打印结果为多少?

  • 答: 20

  • 解释: int[] 是引用类型,ab 指向同一块内存地址。修改 b[0] 的值会影响到 a[0],因为它们指向相同的数组。

string str = “123”; string str2 = str; str2 = “321”; Console.WriteLine(str);请问打印结果为多少?

  • 答: 123

  • 解释: string 是一个特殊的引用类型,但它是不可变的。在这个例子中,strstr2 最初都指向 “123” 这个字符串,但在 str2 = "321"; 时,str 不受影响,因为字符串是不可变的,新的字符串 “321” 会被分配到一个新的内存地址,而 str2 将指向这个新的地址。


7.4 练习题代码

using System;

namespace Lesson05_练习题
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("值类型和引用类型存储上的区别练习题");

            #region 练习题一
            int a = 10;
            int b = a;
            b = 20;
            Console.WriteLine(a);
            //请问打印结果为多少?

            //10
            //值类型:它变我不变
            //值类型是存在栈上
            #endregion

            #region 练习题二
            int[] a2 = new int[] { 10 };
            int[] b2 = a2;
            b2[0] = 20;
            Console.WriteLine(a2[0]);
            //请问打印结果为多少?

            //20
            //引用类型:它变我也变
            //引用类型存在堆上
            #endregion

            #region 练习题三
            string str = "123";
            string str2 = str;
            str2 = "321";
            Console.WriteLine(str);
            //请问打印结果为多少?

            //123
            //string是一个特殊的引用类型,它不遵循它变我也变
            #endregion

        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏