C#阶段性复习--第二章
2.1 数据类型
C#的数据类型主要分为两种 值类型和引用类型
值类型变量 本身包含其数据 ,而引用类型变量包含的是 指向包含数据的内存块的引用或称为句柄
其本质区别是:值类型直接存储其值,而引用类型存储对值得引用
值类型数据存储在栈中,而引用类型存储在堆中
堆和栈得主要区别是:
栈在编译时就分配好空间,在代码中有栈的明确定义
堆是在程序运行中动态分配的内存空间,可以根据程序的运行情况,动态分配内存大小,这个内存空间包含的是对另一个内存位置(地址)的引用,即存放实际引用对象值得地方。
下面对不同数据类型的特性进行一个简单的整理:
一、值类型
1. 整数类型
可以存储整数值,分为有符号 (singal) ,无符号 (unsingal) 类型,没啥特殊性质。
2.实数类型
根据实数的精度、范围等要求,C#为实数定义了浮点类型 (float、double) 和 decimal 类型。
若无精度要求,尝试用 float 来声明实数类型变量。
Decimal 类型是一种专门用于财务计算的类型。 如果要将数值以 decimal 类型来处理,就应该用 M(或 m )将其强制指定为 decimal 类型。 例如:decimal num = 123.567M;
3.布尔类型
布尔类型数据用于逻辑运算,表示真或假的逻辑结果,占一个字节。C# 语言预定了两个常量标识符 true 和 false ,分别表示真和假。
**注意!**在 C# 中,布尔值与整数类型截然不同,布尔型不能与整数类型相互转换,因此,布尔型变量不能用整数来赋值。
4.字符类型
有一类特殊字符,用反斜杠 \ 引导,称为转义字符,用于表示一些无法直接表示的字符。除此之外,Unicode转义序列可用 \u 后跟四位十六进制字符(必须指定全部四位十六进制值)表示,或 \x 后跟差不多四位十六进制字符表示(可以省略前导零)。
例如: \006A 是一个有效的转义序列,而 \u06A 和 \u6A 是无效的。而 \x006A、\x06A 和 \x6A 是有效的,并且对应于同一个字符。
5.枚举类型
枚举元素的默认基础类型为 int 枚举类型是一种独特的值类型。它用于声明一组命名的符号常量。
举个例子。
1 | |
从枚举类型到整型的转换需要 显式转换 来完成。
例如 int x = (int) orientation.north;
在有限组数的描述中,使用枚举类型比使用无符号的整数类型更加直观、易读。
6. 结构体类型
在 C# 中,结构体是一种 用户自定义的值类型数据结构 。结构体可以用于存储一组相关的数据,这些数据可能具有不同的类型,类似于类。但与类不同的是,结构体是值类型而类是引用类型。这意味着结构体的实例在栈上分配内存,而类的实例则在堆上分配内存。
结构体通常用于**存储轻量级的数据,且不能继承特性。**由于结构体是值类型,对结构体变量的赋值和传递会进行值复制,这可以避免意外的副作用。
二、引用类型
引用类型是 C# 应用程序中的主要对象数据类型。而在应用程序执行的过程中,预定义的对象类型以 new 创建对象实例,并且存储在堆中,而引用该实例的变量存储在栈中。
引用类型具有如下特征:
①引用类型的引用变量存储在栈中,被赋值前的值是 null 。实例必须 在托管堆中为引用类型实例分配内存 ;
②使用 new关键字 创建引用类型变量的引用实例( 在托管堆中为引用类型实例分配内存、实例成员初始化等 );
③引用类型与值类型的存储方式
引用类型:引用类型存储在堆中。类型实例化的时候,会在堆中开辟一部分空间存储类的实例。类对象的引用还是存储在栈中。
值类型:值类型总是分配在它声明的地方,作为局部变量时,存储在栈上。
1 | |
- 对象(Object)
- 是 实际的数据实体,存储在堆内存中
- 包含具体的成员数据(字段、属性等)
- 比如:
new Product()会在堆中创建一个Product对象
- 引用变量(Reference Variable)
- 是 指向对象的“遥控器”,存储在栈内存中
- 只保存对象在堆中的内存地址(类似门牌号)
- 比如:
Product phone;中的phone变量
关系示意图
复制
1 | |
在 C# 里面其实叫托管堆,托管堆不同于堆,它是由 ***CLR(公共语言运行库)***管理,当堆中满了之后,会自动清理堆中的垃圾。所以,作为 .net 开发,我们不需要关心内存释放的问题。
2.1 字符串类型
字符串类型是引用类型,不过是特殊的引用类型。当把一个字符串变量赋给另一个字符串变量时,会发生对内存中同一个字符串的两个引用。
1 | |
常量字符串的值用一对双撇号表示,字符串中也可以包含转义符,由于转义符用 \ 开头,因此表示文件路径是,要采用来纳许两个斜杠。例如:
1 | |
C# 语言还提供了另外一种替代方式,就是在字符串常量的前面加上 @,在这个字符后的所有字符都会保持原来的含义,而不会解释为转义符。例如:
1 | |
2.2 数组类型
数组就是 有序的、同一类型数据的集合 。数组实质上是包含多个变量的数据结构,其中每一个变量叫做数组的 元素 ,全部元素的数据类型相同。
说明:
① 数据类型可以是 C# 中任意的数据类型,数组名为一个合法的标识符;[]指名该标识符是一个数组类型变量。
② C# 语言中,数组的声明并不为数组元素分配内存,因此,[] 中不能给定数组中元素的个数。
③ 数组必须在访问前进行初始化。在定义完数组后,必须通过运算符 new 为它分配内存,才能对数组元素进行访问。
2.3 通用类型 object
**在 C# 中,object 是所有数据类型的基类型。它是一种通用类型,可以用来表示任何其他类型的值。**在 C# 中,所有的数据类型都直接或间接地继承自 object 类。因此, obeject 是 .NET 框架中的基本类型。
由于所有数据类型都可以隐式的转换为 object 类型,因此可以使用 object 类型来存储各种类型的数据。
在使用 object 类型时,常见的操作是将特定类型的数据 装箱 到 object 类型中,以及从 object 类型中 拆箱 为特定类型。 装箱是将装箱是将值类型(如 int、float、struct等)转换为通用类型(object),而拆箱是将之前装箱的对象转换回原始的值类型。
1 | |
1 | |
注意:
类型必须严格匹配
装箱会创建值得副本,修改原始值类型不会影响装箱后的对象
1
2
3
4int a = 5;
object boxedA= a;
a=10;
Console.WriteLine(int)boxedA);//输出:5(未被修改)由于 装箱和拆箱操作的性能开销比较大,可能会导致性能问题。
3.var类型
在 C# 中,var 关键字用于声明隐式类型的局部变量。它允许你在不显式指定数据类型的情况下声明变量。相反,数据类型是由编译器根据变量在初始化时赋的值来确定的。
三、常量与变量
1. 常量
(1)整型常量
具体如下
1. 二进制:由数字 0 和 1 组成的数字序列。
2. 八进制: 以数字 0 开头,且其后是由数字 0~7 整数组成的数字序列。
3. 十进制
4. 十六进制:以 0x 或者 0x 开头并且后跟 0~9, A~F 组成的数字序列。
(2)浮点数常量
- 单精度:通常用 F 或 f 结尾。
- 双精度:通常用 D 或 d 结尾。
(3)字符常量 用单引号引起来。
(4)字符串常量
(5)布尔常量
(6)null常量
(7)符号常量
2. 变量
变量具有四个属性:名字、类型、变量值和占用的内存地址。