c#类型、存储和变量



c#程序是一组类型声明   如果广泛的描述C和C++程序源代码的特征,可以说C程序是一组函数数据类型,C++程序是一组函数和类,然而c#程序是一组类型声明。

类型是一种模板   既然c#程序是一组类型声明,那么使用c#就是创建和使用类型。   可以把类型想象成一个用来创建数据结构的模板。这个模板本身不是数据结构,但是详细说明了由该模板构造的对象的特征:

实例化类型   从某个类型模板创建市级的对象,称为实例化该类型。   在c#程序中,每个数据项都是某种类型的实例。这些类型可以是语言自带的,可以是BCL或者其他库提供的,也可以是程序员自己定义的。

数据成员和函数成员   对象也是一种一种类型,这个类型中的数据项个体称为成员,有两种成员:   数据成员保存了与这个类的对象或类本身相关的数据。   函数成员执行代码。函数成员定义类型的行为。

预定义类型   所有预定义类型的名称都是小写字母组成。   ■ 简单类型:   11种数值类型。     不同长度的有符号和无符号的整数类型。     浮点数类型float和double     一种称为decimal的高精度小数类型。与float和double不同,decimal类型可以准确的表示分数。decimal常用于表示货币。   一种Unicode字符类型char。   一种布尔类型bool。bool类型表示布尔值并且必须是true或者false(与C和C++不同,在c#中的数值类型不具有布尔意义)。   ■ 两种非简单类型:     string,它是一个Unicode字符数组。   object,它是所有其他类型的基类。

用户定义类型   有6中类型可以有用户自己创建:   ■ 类类型(class)   ■ 结构类型(struct)   ■ 数组类型(array)   ■ 枚举类型(enum)   ■ 委托类型(delegate)   ■ 接口类型(interface)

  预定义类型的使用是一个单步过程,简单的实例化对象即可。使用用户定义类型是一个两步过程:先声明类型,然后实例化该类型的对象。

堆和栈   运行中的程序使用两个内存区域来存储数据:栈和堆。      ◆ 栈   作为程序员一般不需要显示的对栈进行操作,因为系统会接管所有的栈操作。   栈是一个内存数组,是一个LIFO(last-in first-out,后进先出)的数据结构。栈存储以下几种类型的数据:   ■ 某些类型变量的值;   ■ 程序当前的执行环境;   ■ 传递给方法的参数;      栈的特征:   ■ 数据只能从栈的顶端插入和删除;   ■ 把数据放到站定称为入栈(push);   ■ 从栈顶删除数据称为出栈(pop);

  ◆ 堆   堆是一块内存区域,在堆里可以分配大块的内存用于存储某类型的数据。与栈不同,堆里的内存可以任意顺序存入和移除。   虽然程序可以在堆里面保存数据,但是并不能显示的删除它们。CLR的GC垃圾回收器在判断出程序代码不再访问某项数据时,就会自动的清除无主的堆对象。

值类型和引用类型   数据项的类型定义了存储数据需要的内存大小、组成该类型的数据成员以及该类型能执行的函数。类型还决定了对象在内存中的存储位置————栈或堆。   类型被分为两种:值类型和引用类型,两者的对象在内存中的存储方式不同。   ■ 值类型只需要一段单独的内存,用于存储实际的数据。   ■ 引用类型需要两段内存:     □ 第一段存储市级的数据,它总是位于堆中。     □ 第二段是一个引用,指向数据在堆中的存放位置。   对于值类型,数据存放在栈里。对于引用类型,实际数据存放在堆里面而引用存放在栈里。

存储引用类型对象的成员   ■ 引用类型对象的数据始终存放在堆里。   ■ 值类型对象,或引用类型数据的引用部分可以存放在堆里,也可以存放在栈里,这依赖于实际的环境。

  假设有一个引用类型的实例,名称为MyType,它有两个成员:一个值类型成员和一个引用类型成员,它将如何存储呢?是不是值类型的成员存储在堆里面,引用类型的成员在堆栈之间各存储一半呢?答案是否定的。   因为,对于一个引用类型,其实例的数据部分始终是存储在堆里面。既然两个 成员都是对象数据的一部分,那么它们都是存储在堆里面的,无论它们是值类型还是引用类型。   ■ 尽管成员A是值类型,但它也是*MyType*实例数据的一部分,因此和对象的数据一起呗存放在堆里。   ■ 成员B是引用类型,所以它的数据部分会始终存放在堆里,正如图中“数据”框所示。不同的是,*它的引用部分也被存放在堆里,封装在MyType对象的数据部分中*。

  对于引用类型的任何对象,它所有的数据成员都存放在堆里,无论它们是值类型还是引用类型。

c#类型的分类