Class4 详解类型、变量与对象
课前摘要
- 什么是类型
- 类型在C#语言中的作用
- C#语言的类型系统
- 变量、对象与内存
一、什么是类型
-
强/弱类型编程语言
强:数据受到数据类型的约束 -
C#为强类型(保证数据完整性、安全性)
int x; //32bit(4字节)
long y = 100L; //64bit(8字节)
if(x = 200) //不是bool类型,C#中报错,强类型可以避免,但C语言可以通过
if(200 == x) //C语言中最好这样写,因为C语言类型强度没有C#语言高,可以避免以上的情况发生
if(200 = x) //在C语言中会报错
if(200 == x) //JavaScript,彻底的弱类型
- C#中,有对弱类型的模仿,动态类型
dynamic myVar = 100;
Console.WriteLine(myVar);
myVar = "Mr. Okey";
Console.WriteLine(myVar);
二、类型在C#语言中的作用
一个C#类型中所包含的信息有
- 储存此类型变量所需要内存空间大小
- 此类型的值可表示的最大值、最小值的范围
- 此类型所包含的成员(如:方法、属性、事件等)
- 此类型可由基类派生而来
- 程序运行时,此类型的变量分配在内存的什么位置
Stack简介
Stack Overflow
Heap简介
使用Performance Monitor查看进程的堆内存使用量
关于内存泄露 - 此类型所允许的操作(运算)
程序为执行为程序的静态时期
程序执行为程序的动态时期
- 栈Stack:比较小,比较快,但是可能会爆
- 堆Heap:很大,不会爆,未回收可能会造成内存泄漏(C#中有垃圾收集器,不需要手动释放)
C#中可以写指针,但是要在声明中写insafe
- Process——进程,程序正在运行的实例
- 实例分配到堆中
- 变量可以放在堆/栈中
三、C#语言的类型系统
- C#语言五大数据类型:(类、结构体、枚举、接口、委托)
类型分为引用类型和值类型,根都属于Object类。
值类型包括:结构体、枚举
引用类型包括:类、接口、委托
- 查看类型的方法:右键——go to Difination
四、变量、对象与内存(注意区分值/引用类型)
- 1.什么是变量?
(1)从表面上看,变量的用途时储存数据。
(2)实际上,变量名表示变量的值在内存中的存储位置,并且每一个变量都有一个类型,以决定什么样的值能存入变量,即变量名的位置,就是值的位置(取几个值)
(3)变量共有七种:静态变量、实例变量(成员变量,字段)、数值元素、值参数、引用参数、输出参数、局部变量。
(4)狭义的变量指局部变量,因为其他种类的变量都有自己单独的名字(简单的讲,局部变量就是方法体(函数)里的声明)
(5)变量:以变量名所对应的内存地址为起点,以其数据类型所要求的储存空间为长度的一块内存区域
(6)声明
有效的修饰符组合(opt) 类型 变量名 初始化器(opt)
-
2.值类型变量在内存中的存储(结构体为例)
byte/sbyte/short/ushort(都是结构体类型为例)用execl表格演示
8个bit为一个字节,每个字节提供唯一编号
计算机存在负数,符号位为1,其余位按位取反加一
值类型无实例,所谓”实例“与变量合二为一
int x = new int();
int x; //二者相等
-
3.引用类型的变量与实例
-
引用类型变量与实例的关系:引用类型变量里存储的数据时对象(实例)的内存地址
-
以类为例:
(1)
class Student
{
short a;
int b;
}
Student stu;()
未引用任何实例。
一但看到引用类型,立即在栈中分配4个字节地址,初始值为0
(2)
stu = new Student();
(在堆上分配实例)
将实例在堆上的地址放置于stu引用变量中,堆上符合值内存的储存。
以类有short,int两个字段组成。
注:引用变量为实例在堆中的地址,也就解释了两个孩子同时牵着同一个气球的现象。
- 4.局部变量在Stack上分配内存;实例在Heap上分配内存
- 5.变量默认值:成员变量声明后一般为0,本地变量(在Main中的)不赋初值会报错,
int x;
Console.WriteLine(x);//会报错
- 6.常量不可以被再次赋值
- 7.装箱与拆箱(Boxing与UnBoxing)
(1)装箱
int x = 100;
object obj = x;//object为引用类型
过程:先把值类型的内容copy下来,paste到堆上,找一个地址存储,再在栈上找到四个字节的位置表示引用变量obj,再把粘贴到堆上的地址存放在obj上(初始值为0,在stack上),经历了stack——heap——stack过程,会损失性能
(2)拆箱
int y = (int)obj;
Console.WriteLine(y);
过程:先在stack上分配int类型的值类型参数y(初始值为0);再把obj中对应heap中相应地址的值复制到y中。
(3)总结:把栈上的值类型封装成obj类型的实例为装;把堆上obj实例里的值拆成要求数据类型放到栈上为拆。