C#数据类型-数值类型

1,412 阅读5分钟

📙 学非探其花,要自拔其根

平时学到、用到的都是零零散散的知识点,写这些呢,就是为了做一个系统性的总结,有错误的地方欢迎大家指正。

值类型与引用类型

  • 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 \pm 1.5 \times 10-45 ~ \pm 3.4 \times 1038 System.Single F 或 f 7
double 64bits \pm 5.0 \times 10-324 ~ \pm 1.7 \times 10308 System.Double D 或 d 15 ~ 16
deciaml 128bits \pm 1.0 \times 10-28 ~ 大约\pm 7.9 \times 1028 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...