C#中值类型和引用类型---(1)值类型的讲解

前言:在c#中,所有的数据类型都可以称为“对象”,因为所有数据类型都是一个封装好的类。这一点与c/c++不同。

  •  为什么这么说呢?看代码:
int i = int.MaxValue;//取int的类型的最大值给i

1.值类型和引用类型:

        我们所学的值类型和引用类型究竟是什么:

  •          值类型:基本数据类型:(int , bool , double ,float ,byte,short ,long)(struct enum)等。
    • 其中一些基本类型的字节如下:
      • byte:1 字节;
      • bool:(true false)
      • int :4 字节
      • short:2字节
      • long:8字节
  •          引用类型:(类,接口,委托等)

 2.值类型特殊情况:

2-1.不能大字节变量赋值给小字节变量,可以小字节赋给大字节。(bool类型不能赋值给其他值。)
int i = 1;
short b = i;//也不能在声明的时候进行隐式转换

    如上代码:报错。

        原因:当我们不同类型进行赋值的时候会出现隐式转换的现象。上面所说因为我们的数据类型都是一个类。相当于我们变量名赋值的话会出现“隐式转换的拷贝构造”,也就是说隐式转换是需要所有属性都相同才能赋值,否则不行。

        很明显,我们的int占用4个字节,里面的属性肯定很多,和short的属性不相匹配因此无法转换。如果我们非要转换可以使用强制转换,或者as语法。如下代码:

int i = 1;
short b;
b = (short)i;

2-2.值类型一般也会产生装箱拆箱的操作:

        装箱:把值类型copy,丢到内存堆里面去,装入转换成object类型

int i = 0;
object o = i; 

        拆箱:把object类型转换为值类型

int b = (int) o ;

2-3.值类型变量相互赋值的时候,是copy副本来赋值的。

        1.也就是说值类型是,把10的值copy一份给了b,而不是把a的地址引用给b,b改变值,a不会变。

int a = 10;
int b = a;

2-4值类型的存储地址是在栈区。

        栈区的特点:先进后出。

2-5值类型会被系统自动回收内存。

2-6值类型一般都会运行比较快。

特殊点:struct

        当struct中存在着引用类型的时候,struct的变量不是变成了另一个变量的引用。

例子如下:虽然唯一哈希值是一样的。但是本质地址是不一样的,所以num地址也是不一样的。两个不同的对象可能具有相同的哈希值。这种情况被称为哈希碰撞。哈希算法设计目的是尽量避免哈希碰撞,但无法完全避免。

public class Score
    {
        public int Chinese { get; set; }
        public int Math { get; set; }

        public int English { get; set; }
    }
internal class Program
    {
        public struct Student
        {
            public Score score;
            public int num;
        }
        static void Main(string[] args)
        {

            Student s;
            s.score = new Score();
            s.num = 0;

            Student S1 = s;
            S1.score.Chinese = 100;
            S1.num = 1000;
            Console.WriteLine("S1 的语文成绩是:" +  " num is " + S1.num);
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.num);


            Console.WriteLine("S1 的语文成绩是:" +" num is " + S1.GetHashCode());
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.GetHashCode());
            Console.WriteLine(Object.ReferenceEquals(s,S1));
            Console.ReadLine();
        }
}

  运行结果:

 但是呢,结构体里面若是有引用对象的话,这是里面的成员会引用同一个空间:根据上面代码改动:

namespace Test0
{
    public class Score
    {
        public int Chinese { get; set; }
        public int Math { get; set; }

        public int English { get; set; }
    }
    internal class Program
    {
        public struct Student
        {
            public Score score;
            public int num;
        }
        static void Main(string[] args)
        {

            Student s;
            s.score = new Score();
            s.num = 0;

            Student S1 = s;
            S1.score.Chinese = 100;
            S1.num = 1000;
            Console.WriteLine("S1 的语文成绩是:" +  " num is " + S1.num);
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.num);


            Console.WriteLine("S1 的语文成绩是:" +" num is " + S1.GetHashCode());
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.GetHashCode());
            Console.WriteLine(Object.ReferenceEquals(s.score,S1.score));
            Console.ReadLine();
        }

    }
}

运行结果:

 

我们说字符串也是一个引用类型,假如我们把成员的引用类型换成字符串呢?

namespace Test0
{
    public class Score
    {
        public int Chinese { get; set; }
        public int Math { get; set; }

        public int English { get; set; }
    }
    internal class Program
    {
        public struct Student
        {
            public String score;
            public int num;
        }
        static void Main(string[] args)
        {
          
            Student s;
            s.score = "100000000";
            s.num = 0;

            Student S1 = s;
            S1.score = "99999999";
            S1.num = 1000;
            Console.WriteLine("S1 的语文成绩是:" +  " num is " + S1.num);
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.num);


            Console.WriteLine("S1 的语文成绩是:" +" num is " + S1.GetHashCode());
            Console.WriteLine("s 的语文成绩是:" +  " num is " + s.GetHashCode());
            Console.WriteLine(Object.ReferenceEquals(s.score,S1.score));
            Console.ReadLine();
        }

    }
}

运行结果:

 

为什么明明这是引用类型,而不是同一个地址呢?

工作繁忙,我们下期分享。

------------------------------------------------------------------------------------------------------------------

感谢收看!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇宙技术员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值