C#基础——基本概念

一、C#、CLR、.NET Framework(.NET框架)

       C#是开发语言,用于编写代码;

       CLR(Common Language Runtime,公共语言运行库),在运行期间进行内存管理、代码安全验证、代码执行、垃圾收集等(CLR有一项服务GC(Garbage Collector,垃圾收集),可以自动管理内存,减轻程序员负担);

       .NET Framework是开发框架,可看作是一个独立发布的软件包,其中包含了CLR、类库以及相关的工具等开发环境。

        C#代码需要依托.NET框架编译和运行。

二、编译 

C#编译分两步走:

       第一步是编译成中间语言CIL,生成计算机可识别的输出文件——程序集(包含程序元数据及对其他程序集引用的元数据),程序集可以是可执行文件(.exe)或者动态链接文件(.dll)

       第二步是编译成本机代码并执行,即在本机上搭建.NET环境,将程序集中的可执行代码在需要的时候由实时编译器编译,然后被缓存以备后来的程序执行。一旦CIL被编译成本机代码,CLR就在其运行的时候管理它,执行内存及检查之类的工作。

三、托管和非托管

       .NET环境中,系统的资源分为托管资源和非托管资源。

       托管代码:为.NET框架编写的代码称为托管代码,需要CLR。

       非托管代码:不在CLR控制之下运行的代码,比如Win32C/C++ DLL,成为非托管代码。

四、堆和栈

       堆(heap):在C#中,又叫作托管堆,用于托管(存储)实例对象(new对象),可动态分布存储空间,能够存储大量数据。灵活性高,但,效率不高。对于堆的回收,C/C++是手动回收,.NET是CLR管理,满了之后,GC自动回收,无需担心内存释放问题。

       (内存)栈(stack):先进后出,后进先出。入栈时,自动分配确定内存(譬如,int,4个字节),出栈时,自动清理所占的内存。灵活性不高,但,效率高。(区别数据栈)

       堆存放引用类型对象,由CLR释放;栈存放函数的参数、局部变量、返回数据等值对象,由编译器自动释放。

五、值类型和引用类型

       引用类型创建时,runtime会为其分配两个空间,一块空间分配在堆上,存储引用类型本身的数据,另一个块空间分配在栈上,存储对堆上数据的引用(实际上存储的堆上的内存地址,也就是指针),如类对象的引用还是存储在栈中。

       值类型创建时,runtime会为其分配一个空间,这个空间分配在变量创建的地方。作为方法内局部变量时,则随方法入栈;作为引用类型的成员变量时,则跟随引用类型,存储在堆上。如,作为类对象的字段时,则跟随类存储在堆里。

       栈是一个有逻辑顺序的结构,堆则是杂乱地堆在一起的,比较耗能。引用类型占空间较大,且分配空间不确定,故不直接存在栈中而是存放在堆中,通过栈中的指针引用。

  • 栈内存存储的是局部变量而堆内存存储的是实体;
  • 栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
  • 栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

①引用类型和值类型都继承自Systerm.Object类。不同之处,几乎所有的引用类型都是直接从Systerm.Object继承,而值类型则是继承Systerm.Object的子类Systerm.ValueType类。

②我们在给引用类型的变量赋值的时候,其实只是赋值了对象的引用;而给值类型变量赋值的时候是创建了一个副本(就是克隆了一个变量)。

五、指针

1、首先配置项目,允许不安全代码

2、指针定义

 C#中可定义为指针的类型:sbyte、byte、ushort、int、uint、long、ulong、char、float、double、decimal、bool、struct,其中struct只能包含非托管类型(值类型数据)

定义指针说明
int* p整型指针
int** p指向整型指针的指针
char* c指向字符的指针
int*[] arr整型一维数组指针

3、写代码时,使用关键字unsafe

fixed:用户暂时固定托管代码中引用类型的位置(固定时间越短,固定地址越小越好,以防产生内存碎片)

 stackallc:给指针分配内存

unsafe void ClassPointer() 
{
     Person p = new Person();//堆中的存储空间是随意的,地址不固定
     //fixed:临时固定地址, pIY = &p.Y
     //stackalloc:从内存分配地址
     fixed (int* pIX = &p.X)
     {
         int* ptr = stackalloc int[1];

         char* cptr = stackalloc char[26];
         for (int i = 0; i < 26;i++ )
         {
             cptr[i] = (char) (i+65);
         }
         for (int i = 0; i < 26;i++ )
         {
             Console.WriteLine(string.Format("{0}:{1}",(int)&cptr[i],cptr[i]));
         }
     }
}



class Person
{
     //定义成变量才能正确取址
     public int X  = 1;
     //定义成属性,则报错“无法获取给定表达式的地址”
     public int Y { get; set; } = 2;
}

参考:

https://blog.csdn.net/lidandan2016/article/details/77868043

https://www.cnblogs.com/zd1994/p/4424329.html

https://www.cnblogs.com/xiaodongy/p/7989711.html

https://www.cnblogs.com/jasonlny/p/3203439.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值