c#之类型,变量,对象

1.类型

又名数据类型,是性质相同的值的集合,并且有自己一套专门的操作运算。 内存是程序运行的区域,数据放在内存中。

(1)类型在c#中的作用

·存储此类型变量所需要的内存空间大小。比如说此时类型是int类型,那我们就会知道这个变量占用的内存大小。

·可以知道此类型的值的最小最大范围。

(2)程序的静态和动态:就是说程序未运行起来的时候是静态,这个程序运行起来的时候就是动态的。(不是我们一般说的 那种加static的静态)当我们运行一个程序的时候可以说这个程序从静态向动态进行转换。

(3)堆和栈的简介

程序运行起来之后会把内存分成2个区域,一个是栈,一个是堆。栈是给方法调用的,堆是存放对象实例的。栈很小只有2M左右,但是很快,堆可以达到几个G。当算法没写好或者程序有错误的时候,会造成栈溢出。对于堆来说不会出现溢出的问题,但是如果我们任意的在往堆上分配对象,没有释放,会造成内存的浪费,一般称为内存泄漏。

如下面的方法,展示了栈溢出的情况,一直调用BadMethod方法,一直往栈中插入值。

namespace TestClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Bad bad = new Bad();
            bad.BadMethod();

            Console.ReadKey();
        }
    }
    class Bad
    {
        public void BadMethod()
        {
            int x = 1;
            this.BadMethod();
        }

    }


}

 (4)c#的五大数据类型

(5)变量,内存,对象

   

 从表面上讲,变量的用途是存储数据。

实际上,变量表示了存储位置,不并且每个变量都有一个类型,以决定什么样的值能够存入变量。

当程序运行的时候是在内存中运行的,没有运行的时候可以看做是在硬盘中,程序运行中,变量的值也是在内存中存储的。

比如定义:int x=100;计算机会x当做一个标签,这个标签对应着内存中的一个地址,100这个值就存在这个地址指向的内存中。int类型占用4个字节,从这个地址往后的4个字节的内存来保存这个变量,所以说明只有小于等于4字节的值才会放到这个变量中。

变量一共有7种:静态变量,实例变量,数组元素,值参数,引用参数,输出形参,局部变量。

变量就是以变量名所对应的内存地址为起点,以其数据类型所要求的存储空间为长度的一块内存区域。

(6)值类型与引用类型

 计算机是以字节(byte)为基础单元进行数据的存储读取,并且为每个字节都准备了一个唯一的编号,我们通常所说的内存地址就是计算机科学中说的字节的编号。

 1.值类型

  比如:int x=10;

此时计算机系统一看是值类型,就会在内存中找到空闲的栈内存区域,并根据变量的数据类型,取得对应的字节长度一块区域,将10以二进制的方式存储到内存中。

2.引用类型

 class Program
    {
        static void Main(string[] args)
        {
            Student student;
            student = new Student();
            Console.ReadKey();
        }
    }
    class Student
    {
        uint ID { get; set; }
        ushort Score { get; set; }

    }

看上面的代码,在创建student对象的时候,计算机系统一看是引用类性,会在栈内存中找到空闲的内存区域,然后默认分配4个字节的长度。

    student = new Student();这一步操作则会在堆内存中找到空闲区域,创建分配一个Student实例,在堆中的这个内存中才是存储ID,Score这些信息,然后把堆上的这个内存地址保存在student这个对象中。将这个内存地址转化成二进制存放到栈内存中。

如果后续加上下列代码:

           Student student2;
            student2 = student;

此时会在栈内存中先默认创建一个4字节长度的内存区域,之后再将student对象在栈中存储的实例的地址信息复制到student2中,此时这个2个对象指向的就是同一个地址了。

注意:在上述代码中,类Student中的2个变量是值类型的,但是他们的值是随着实例存储在堆中的,而不是栈上的。这就是通常说的值类型的值可能在栈上存储,也可能在堆上存储。也可以记为局部变量(类中方法体内部的变量称为局部变量)是存储在栈上的。所以在方法内部的student对象的值存储在栈上,因为是在方法体内创建的一个变量,但是new Student()是创建了实例,所以是存储在堆上。而且类中的ID,Score我们称之为字段,或者成员变量,不是局部变量,所以存储在堆上。

实例构造函数的内存机理:

class Program
    {
        static void Main(string[] args)
        {
            Student student  = new Student(1,"name");
             
            Console.ReadKey();
        }
    }
    class Student
    {
        int ID { get; set; }
        string  Name { get; set; }
        public Student(int id,string name)
        {
            this.ID = id;
            this.Name = name; 
        }

    }

上面代码实现了一个带参数的构造函数,  Student student  = new Student(1,"name");这一步会先在栈上找到一块内存区域, 然后实例化,在堆上找到一块内存区域存放类中的ID,Name。但是这次调用了带参数的构造器,值类型的id值会在直接放到最开始找到的堆内存中,对于引用类型的name参数则又会在堆上另找一块内存区域存放字符串的值,最开始的内存区域剩下的地方用来存新找的内存地址与值类型的值。

 

 

 

(7)拆箱与装箱

  1.装箱

  下面就是一个装箱的代码:都是局部变量

int x=10;
object  o=x;

int x=10;这一步会在栈内存中创建一个4个字节长度的内存区域,Object o;这一步会在栈上创建一个内存区域来存储对象o。当计算机发现Object所要引用的值是在栈内存中存储的数据时候,会复制这个对象在栈内存中存储的数据,然后到堆上找到一块内存空间,存储这个值,然后把这个堆地址赋给对象。在本例中,就是把堆地址赋给对象o。

2.拆箱

int y=(int)o

此时会在栈内存中存储一个对象y,然后根据对象o的存储的地址找到堆中的数据,然后赋给y。

所以拆箱装箱会损失性能

 

 

 

 

 

引用于:https://www.bilibili.com/video/BV13b411b7Ht?p=7

 

posted @ 2020-06-22 23:59  安静点--  阅读(695)  评论(0编辑  收藏  举报