
📙 学非探其花,要自拔其根
平时学到、用到的都是零零散散的知识点,写这些呢,就是为了做一个系统性的总结,有错误的地方欢迎大家指正。
值类型与引用类型
- C sharp 中的数据类型可以简单的分为值类型(结构、枚举)和引用类型(类、接口、字符串、数组、委托、指针)。
- 值类型变量或常量的内容仅仅是一个值,例如整数int,小数float/double,布尔值等,换句话说就是,变量引用的位置就是值在内存中的位置。
- 引用类型比较复杂,它友两部分组成:对象和对象引用。而引用类型的变量中的内容存储的是对‘数据’存储位置的引用,不是直接存储‘数据’。
- 存储开销:
- 值类型所占内存大小就是存储字段所需内存。例如Book所需内存就是price、title、author内存的和。
- 引用类型要求为引用和对象单独分配存储空间。对象除占用了和字段一样的字节数之外,还需要额外的管理空间开销。
值类型实例的赋值总是会进行实例复制。 引用类型变量的赋值只会复制引用。
public struct Book
{
public decimal price;
public string title;
public string author;
}
1.1 整数类型
C#有8种整数类型
| 类型 | 大小(位) | 范围(包括边界值) | BLC名称 | 后缀 |
|---|---|---|---|---|
| 有符号(signed) | ||||
| sbyte | 8bits | -27 ~ 27 - 1 | System.SByte | |
| short | 16bits | -215 ~ 215 - 1 | System.Int16 | |
| int | 32bits | -231 ~ 231 - 1 | System.Int32 | |
| long | 64bits | -263 ~ 263 - 1 | System.Int64 | L 或 l |
| 无符号(unsigned) | ||||
| byte | 8bits | 0 ~ 28 - 1 | System.Byte | |
| ushort | 16bits | 0 ~ 216 - 1 | System.UInt16 | |
| uint | 32bits | 0 ~ 232 - 1 | System.UInt32 | U 或 u |
| ulong | 64bits | 0 ~ 264 - 1 | System.UInt64 | UL或ul |
1.2 实数类型
3种实数类型,其中float和double称为浮点类型。
从技术上讲,decimal也是一种浮点类型,但是C#语言规范并没有将其定义为浮点类型
| 类型 | 大小(位) | 范围 | BLC名称 | 后缀 | 有效数字 |
|---|---|---|---|---|---|
| 实数 | |||||
| float | 32bits | System.Single | F 或 f | 7 | |
| double | 64bits | System.Double | D 或 d | 15 ~ 16 | |
| deciaml | 128bits | System.Declmal | M 或 m | 28 ~ 29 |
1.3 字面量(literal)
字面量或字面值(literal value)表示源代码中固定的值,如下代码中23、0x7F、1_000_000、2.3;
int x = 23;
long y = 0x7F;
int millon = 1_000_000;
double d = 2.3;
1.4 类型的确定
数值literal的类型推断
- 默认情况下编译器会推断一个数值literal是double还是整数类型:
- 如果包含小数点,或以指数形式展现,那么就是double类型
- 否则按照以下顺序,解析成能够存储该值的第一种数据类型:int、uint、long、ulong
整数字面量的类型确定
- 没有后缀的数值字面量,按照以下顺序,解析成能够存储该值的第一种数据类型:int、uint、long、ulong
- 具有后缀U或u的数值字面量按照以下顺序,解析成能够存储该值的第一种数据类型:uint、ulong
- 具有后缀L或l的数值字面量按照以下顺序,解析成能够存储该值的第一种数据类型:long、ulong
- 如果数值字面量的后坠是UL或LU,则解析成ulong类型
字面量的后缀不区分大小写,但对于long,推荐使用大写字母L,因为小写字母l和数字1不好区分
Console.WriteLine(1.0.GetType()); //System.Double
Console.WriteLine(1E06.GetType()); // System.Double
Console.WriteLine(1.GetType()); //System.Int32
Console.WriteLine(0xF0000000.GetType()); //System.UInt32
Console.WriteLine(0x100000000.GetType()); //System.Int64
Console.WriteLine(0b1100_0010.GetType()); //System.Int32
数值的后缀
- U、L很少使用,因为uint、long、ulong要么可以被推断出来,要么可以从int隐式转换过来
- D其实很多余
- F和M比较有用,当指定float或decimal的字面量的时候,必须加上

1.5 类型转换
1.5.1 整数类型转换
- 当目标类型可以容纳原类型的时候,整数转换是隐式的
- 否则就需要显示转换
如下,long表示的范围比较大,其中包含int的所有值,所以int可以隐式转换为long,short也在long的范围之内,变量b的值为123456,而short类型的范围是-32768~32767,此时123456不在short范围之内, 所以无法进行隐式转换。
int a = 123456;
long b = a;
short c = (short)b;
1.5.2 浮点型转换
- float在double范围之内,所以float可以隐式转换为double
- double必须显示转换为float
1.5.3 浮点型和整数类型转换
- 所有整数类型都可以隐式的转换为浮点型
- 反过来则必须进行
1. 当从浮点型转换为整型时,小数部分是被截断的,没有舍入。 2. 把一个很大的整数隐式转换为浮点类型之后,会保证量级不变,但是偶尔会丢失精度。这是因为浮点类型有更多的量级,而精度可能不足。
int i = 1000000001;
float f = i;
int j = (int)f;
Console.WriteLine(i);//1000000001
Console.WriteLine(f);// 1E+09
Console.WriteLine(j);//1000000000
1.5.4 decimal转换
- 所有的整数类型都可以被隐式转换为decimal,这是因为decimal可以表示所有可能的C#整数类型
- 反过来则必须进行显示转换
1.6 特殊整数类型运算
1.6.1 整数除法
-
整数类型的除法会截断余数
int x = 5/2; //2 -
用字面量常量0做除数将会产生编译错误(如图)

-
用值为0的变量做除数会产生运行时错误

to do...