一:电脑是用什么来存储所使用的数据
这个问题用一句话比较笼统的概括那就是:电脑使用内存来记忆计算时所使用的数据
在现实生活中的数据各种各样,整数、小数、字符串、字符等等,它们的类型是不一样的,所以你要想在计算机中使用这些类型,就必须在内存中为它申请一块合适的空间
二:基础数据类型
首先要了解一点:C#认可的基础数据类型并没有内置于C#语言中,而是内置于.net Framework中(例如在c#中声明一个int类型的数据时,声明的实际上是.net结构中System.Int32的一个实例),并且C#中的所有类型都是继承自System.Object,包括定义一个类也是隐式继承自System.Object
c#有15个预定义类型,其中13个是值类型,两个是引用类型(string和object)
为什么c#中的int取值范围是-2的31次方到2的31次方-1
计算机中底层存储数据时存的是二进制数字,但是并不是直接存该数字对应的二进制数字,而是存该数字对应的二进制数字的补码
用sbyte举例子,首先sbyte是8位有符号整数,所以它的取值范围应为它的补码所能表示的最大数。第一位为符号位,首先分析正数,因为正数的原码和补码相同,则表示的最大整数的原码和补码为01111111(127)。再分析负数,首先想到的最小整数的原码应和正数对称,11111111(-127),11111111所对应的补码为10000001,但是并非如此,最小整数的补码应该为10000000(-128)
解释一下为什么是10000000(-0)并且能够表示为-128,因为11111111(-127)的补码为10000001,-1的补码为11111111,-127+(-1)=10000001+11111111=10000000(-0),所以计算机中将8位的-0视为-128,这样-0也就有了意义
原码、反码、补码
三:C#是静态类型并且类型安全的语言
C#是静态类型语言。静态类型语言是在编译时需要声明所有变量的类型,例如C#、JAVA、C++等,而动态类型语言在编译时不需要声明变量类型,例如Python、Rub。虽然C#现在支持使用var来声明变量,但这并不是把C#变为了动态语言,其类型在编译时就被推断出来,例如下面的代码声明c为"liu",这时候编译器在编译阶段已经推断出c是string类型,再将c赋值为int类型的11,在编译阶段就会报错,但这在动态类型语言中是被允许的
int a = 11;//静态类型语言
b = 11;//动态类型语言
//C#中允许使用var关键字定义,但这并不是把C#变为了动态语言,其类型在编译时就被推断出来
var c = "liu";
c = 11;//会报错
C#是类型安全的语言,它不存在类型转换时的隐患,例如C、C++是类型不安全的语言。在C#中将一个类型转换成另一个类型,会首先在编译时检测是否正确,如果通过编译后则会在程序运行时通过Mono运行时检查转型操作,如果没有通过转型检查会抛出异常
四:类型转换
——显式转换与隐式转换
隐式转换:C# 默认的以安全方式进行转换,从小类型转换为大类型(例如int类型的变量赋值给float类型的变量),从派生类转换为基类,绝不会导致数据丢失
显式转换:即强制类型转换,显式转换需要强制转换运算符,而且强制转换可能会造成数据丢失
——XXX.Parse(数字字符串)
此方法只能把数字字符串类型("3.14"可以,"abc"不行)转换为其他类型。如果转换成功则输出相应的值,如果转换失败则输出异常
——XXX.TryParse(数字字符串,out 输出的结果)
此方法只能把数字字符串类型("3.14"可以,"abc"不行)转换为其他类型
这个方法是XXX.Parse的优化版,如果转换成功则输出相应的值,如果转换失败则输出0,不会出现异常
XXX.TryParse不可以接受NULL值。它内部实现其实是对XXX.Parse()做了一个异常处理,如果出现异常则返回false,并且输出0
——Convert.ToXXX(任何类型的数据)
此方法可以转换任意类型的数据,使用此方法转换数字类型时会进行特殊的四舍五入(如果为x.5则返回两个整数数字之之间的偶数,否则直接进行四舍五入,例如4.5返回4,5.5返回6)
如果转换成功则输出相应的值,如果转换失败则输出异常
Convert.ToXXX可以接受NULL值,返回值为0。它内部实现其实是参数如果为 NULL,则直接返回 0
总结:如果是两个数字类型进行转换则直接使用(XXX)数据,如果是将数字字符串类型转换为数字类型则使用XXX.Parse(数字字符串)或XXX.TryParse(数字字符串,out 输出的结果),如果是其他类型转换则再考虑Convert.ToXXX(任何类型的数据)
五:可空类型Nullable
我们都知道,int类型的默认值为0,bool类型的默认值为false,不能为他们赋null,所以C#提供了一个可空类型Nullable,可以让任何类型赋值null
int? a = null; //等同于Nullable<int> a = new Nullable<int>();
int a; //默认值为0
int? a //默认值为null
Null合并运算符:
Null合并运算符必须比较两个默认值为null的数据
如果第一个操作数为null,则返回第二个操作数的值,否则返回第一个操作数的值using System; class Test { static int a; static void Main() { int? a = null; int? b = 2; int c; c = a ?? 10; Console.WriteLine(c); //10 c = b ?? 10; Console.WriteLine(c); //2 } }