c#基础二 数据类型与异常类型
数据类型:
一类是值类型,一类是引用类型。
值类型分为 简单类型、枚举类型、结构类型、和 可空类型。
引用类型 分为 类类型、接口类型、数组类型、委托类型。
|
类别 |
说明 |
|
|
值类型 |
简单类型 |
有符号类型:sbyte,short,int,long |
|
无符号类型:byte,ushort,uint,ulong |
||
|
Unicode字符集:char |
||
|
IEEE浮点型:float,double |
||
|
高精度小数型:decimal |
||
|
布尔型:bool |
||
|
枚举类型 |
enum E{…}形式的用户定义的类型 |
|
|
结构类型 |
struct S{…}形式的用户定义的类型 |
|
|
可控类型 |
如:int? 表示可以为null的int类型 |
|
|
引用类型 |
类类型 |
所有类的基类:Object |
|
Unicode字符串型:string |
||
|
class C{…}形式的用户定义的类型 |
||
|
接口类型 |
interface I{…}形式的用户定义的类型 |
|
|
数组类型 |
一维和多维数组,例如int[] 和 int[,] |
|
|
委托类型 |
delegate int D(…)形式的用户定义的数据 |
|
值类型和引用类型的区别: 值类型变量直接保存变量的值,引用类型变量保存的是数据的引用地址,引用类型的变量也叫对象。当把一个值变量赋值给另一个值变量时,会在堆栈(stack)中保存两个完全相同的值,因此对一个变量的操作不会影响到其他变量;对于引用类型的变量,对一个变量的数据的操作就是对这个变量在堆中的数据进行操作,如果两个引用类型的变量引用同一个对象,实际含义就是他们在堆栈中保存的堆的地址相同,因此对一个变量的操作就会影响到引用同一个对象的另一个变量。
|
特性 |
值类型 |
引用类型 |
|
变量中保存的内容 |
实际数据 |
指向实际数据的引用指针 |
|
内存空间配置 |
堆栈 |
受管制的堆 |
|
内存需求 |
较少 |
较多 |
|
执行效率 |
较快 |
较慢 |
|
内存释放时间点 |
执行超过定义变量的作用域时 |
由垃圾回收机制负责回收 |
|
可以为null |
不可以 |
可以 |
整形:
|
类型 |
说明 |
取值范围 |
|
Sbyte |
1字节有符号整数 |
-27~+(27-1) 即-128~127 |
|
Byte |
1字节无符号整数 |
0~(28-1),即0~255 |
|
Short |
2字节有符号整数 |
-215~+(2 15-1),即-32768~+32767 |
|
ushort |
2字节无符号整数 |
0~216-1,即0~65536 |
|
Int |
4字节有符号整数 |
-231~231-1,即-2 147 483 648~+2 147 483 647 |
|
Uint |
4字节无符号整数 |
0~232-1,即0~4 294 967 295 |
|
Long |
8字节有符号整数 |
-263~+263-1 |
|
Ulong |
8字节无符号整数 |
0~264-1 |
浮点型:
|
类型 |
说明 |
精度 |
取值范围 |
|
Float |
4字节IEEE单精度浮点数 |
7 |
1.5*10-45~ 3.4*1038 |
|
Double |
8字节IEEE双精度浮点数 |
15~16 |
5.0*10-324 ~1.7*10308 |
|
Decimal |
16字节浮点数 |
28~29 |
1.0*10-28~7.9*1028 |
布尔型:
true / false
字符类型与字符串类型:
字符型属于值类型,用char表示,为单个Unicode字符,一个Unicode字符的标准长度为两字节。
赋值方法:(1)char mychar1 = ‘A’;(2) 字母A的十六进制表示:char mychar2 = ‘\x0041’;
字母A的Unicode表示:char mychar3 = ‘\u0041’;
引用类型String类(第一个字母大写),对应的别名为string(第一个字母小写),它实际上就是System.String类。string类型可以方便的实现字符串的复制,连接等各种操作。
字符串也可以包含转义符:string filePath = “C:\\CSharp\\MyFile.cs”;如果在字符串常量前加上@符号,则字符串内的所有内容均不再进行转义:string filePath = @“C:\CSharp\MyFile.cs”;
不同数据类型之间的转换:
对于不同值类型之间的转换:
精度(从小到大):byte-short-int-long-float-double
隐式转换:从低精度、小范围的数据类型转换为高精度、大范围的数据类型。
显示转换:又叫强制转换,将大范围的数据转换成小范围类型的数据,需要用户明确的指定转换的类型,可能造成数据丢失。
如果需要使用显示转换,又不知道会不会丢失数据,可以使用checked 运算符来检验转换是否安全,如 long r = 3000000000; int i = checked((int) r);如果数据丢失,系统会抛出异常。
另外,使用Convert类提供的方法也能进行各种值类型之间的转换.
值类型和Object类型之间的转换:
引:string s = (10).ToString();
数字10只是一个在堆栈上的4字节的值,怎么能实现上面的方法呢?实际上,c#语言是通过装箱来实现的,即先把10转换为引用类型,然后在调用引用类型的方法来实现指定的功能。
装箱:将值类型隐式的转换为Object类型。装箱一个数值会为其分配一个对象实例,并把该数值赋值到新对象中。如:int i =123; object o =i;在堆上开辟空间,存的是和i一样的值,然后在堆栈上创建一个对象o,指向堆上的值。
拆箱:将Object类型显示的转换为值类型。包括两个步骤(1)检查对象实例,确认它是否包装了值类型的数。(2)把实例中的值复制到值类型的变量中。如:int i =123;//值类型
object box = i;//装箱操作 int j = (int )box;//拆箱操作
常量
(1) const 关键字声明,在编译的时候就初始化,只能在声明中赋值,在对程序进行编译的时候,编译器会把所有const常量全部替换为常数。
(2) readonly关键字声明在运行期间才初始化并且只能初始化一次的字段,可以再声明语句时初始化,也可以在构造函数中初始化,初始化以后,该字段的值就不能再改变。
用途:程序员可以根据所使用的构造函数将readonly字段初始化为不同的值。
若在readonly关键字左边加上static,其作用相当于定义一个常量。
变量:
静态变量、实例变量(这两中变量也成为字段)、数组元素、值参数、引用参数、输出参数、局部变量。
匿名类型的变量:
C#3.0提供的一种新类型的变量,匿名类型的变量即程序员不必指定“局部”变量的类型,统统用var来表示。匿名类型实际上仍属于强类型,只不过判断具体类型的工作由编译器完成,用处:
(1) 可以利用匿名类型将一组只读属性封装到单个对象中,而无须首先显示定义属性的类型,如:var student = new {Name = “zhangsan”, Age = 18};相当于先定义一个类,类中定义了Name 和Age属性,然后创建一个该类的对象student,并给两个属性赋值。至于Name和Age属性石什么类型,则由编译器推断。
(2) 用foreach语句遍历某个集合时,如果不知道该集合中的成员应该是什么类型,就可以用var来声明它。
运算符:
只介绍几个不常用的
Typeof运算符:获取类型的System.Type对象,如System.Type type = typeof(int);
Is 运算符:检查对象是否与给定类型兼容,x is T 含义为如果x 为T,返回true;否则返回false,例如: static void Test(object o ){if(o is Class1) a=(Class1)o;}
As运算符:x as T含义为返回类型为T 的x,如果x不是T,则返回null。例如:Class1 c =new Class1();Base b = c as Base; if(b!=null){…}
格式化输入输出
控制台输出:
bool flag = false; Console.Write(flag);
int age = 18; Console.Write(age);
string s = “abc”;Console.Write(s);
Console.WriteLine();
Console.WriteLine(“{0},{1},{2}”,flag,age,s);//数字只跟参数位置有关系
控制台输入:
Read: 返回整形int,但这个返回值和用户输入的整数并不相同,而是输入的数对应的ASCII值,需要用户将输入转换为字符格式后才能进行转换。如:
int i = Console.Read();
if (i == '1')
{
Console.WriteLine("{0}equal char 1",i);
}
else
{
Console.WriteLine("{0} not equal char 1",i);
}
若输入1,则返回:49 equal char 1
ReadKey:Console类的ReadKey方法用于从标准输入流读取用户按下的字符或功能键,并将被按下的键显示在控制台窗口中。不带参数的ReadKey方法会返回一个ConsoleKeyInfo类型的对象,描述ConsoleKey常数和对应于按下的键的Unicode字符。如:
ConsoleKeyInfo c;
do
{
c= Console.ReadKey();
}while(c.Key != ConsoleKey.Escape);
其功能是等待用户按下<ESC>键。
ReadLine:string s = Console.ReadLine();
字符串的格式化输出
格式化输出的一般形式为:{N [,M] [:格式码]},[ ]表示其中的内容为可选项。
N从0开始的整数,表示第几个参数;
M为可选整数,表示最小长度,若参数N 的长度小于M,就用空格填补,若M为负,则左对齐,若M为正,则右对齐,若未指定M,则默认为0;
格式码为可选的格式化代码字符串:
|
格式符 |
含义 |
示例(int i=10;double=10.5) 只写Console.WriteLine()中的内容 |
结果 |
|
C |
将数字按照金额形式输出(若比两位长则四舍五入,如:¥10.00,¥10.50) |
(“{0:C}”,i) (“{0:C}”,x) |
¥10.00 ¥10.50 |
|
D |
输出十进制整数 |
(“{0:D}”,i) (“{0:D5}”,i) |
10 00010(左侧补0) |
|
F |
小数点后固定位数(默认为两位) |
(“{0:F}”,i) (“{0:F4}”,x) |
10.00(默认取两位) 10.5000(小数补够4位) |
|
0 |
0占位符,如果数字不够指定的占位符位数,则左边补0至占位符位数;若数字位数超过指定的占位符位数,则按原数字实际位数原样输出。若小树部分位数超出指定占位符位数,多余的部分四舍五入 |
(“{0:00000}”,123) (“{0:000}”,12345) (“{0”0000}”,123.64) (“{0:00.00}”,123.6484) |
00123 12345 0124 123.65 |
|
# |
#占位符,对整数部分,去掉数字左边的无效0,小数部分,按照四舍五入原则处理后,去掉右边的0.如果这个数是0,而又不想让它显示的时候,#占位符很管用 |
(“{0:####}”,123) (“{0:####}”,123.64) (“{0:####.###}”,123.64) (“{0:####.##}”,0) (“{0:####.##}”,123.648) |
123 124 123.64
123.65 |
对于字符串来说,可以直接利用格式化输出得到希望的格式:如
string s = string.Format(“{0,30}”, ‘ ‘);//得到30个空格的字符串
string s =string.Format(“{0,-20}”,”15”);//得到左对齐长度为20的字符串
数字的格式化输出
string.Format方法可以将数字按照希望的格式得到对应的字符串
string s = string.Format(“{0:d6}”,123);//得到000123;
strint s = string.Format(“{0,-7}”,123);//得到123 ;
string s = string.Format(“{0:p}”,0.123);//得到12.6%
string s = string.Format(“{0:n4}”,12345.23456);//得到12,345.2346(整数部分每三位用逗号分割,小数部分保留4位)
日期和时间的格式化输出
|
格式字符串 |
说明 |
|
d |
一位数或两位数的天数 |
|
dd |
两位数的天数。一位数的天数前面加0 |
|
ddd |
三个字符的星期几缩写 如:三 |
|
dddd |
完整的星期几名称,如:星期三 |
|
h |
12小时格式的一位数或两位数小时数 |
|
hh |
12小时的两位数小时数,一位数前面加0 |
|
H |
24小时格式的一位数或两位数小时数 |
|
HH |
24小时格式的两位数小时数,一位数前面加0 |
|
m |
一位数或两位数分钟数 |
|
mm |
两位数分钟值 |
|
M |
一位数或两位数月份值 |
|
MM |
两位数月份值 |
|
MMM |
三个字符的月份缩写 |
|
MMMM |
完整的月份名 |
|
s |
一位数或两位数秒数 |
|
ss |
两位数秒数 |
|
t |
单字母A.M.或P.M.的缩写(A.M.将显示为A) |
|
tt |
两字母A.M.或P.M.的缩写(A.M.将显示为AM) |
|
y |
一位数的年份(2001显示为1) |
|
yy |
年份的最后两位数(2001显示为01) |
|
yyyy |
完整的年份 |
1 DateTime dt = new DateTime(2009, 12, 25, 12, 30, 40);
2 Console.WriteLine("{0:yyyy年MM月dd日 HH:mm:ss ddd(dddd),MMM(MMMM)}", dt);
3 //若想显示英文形式的月份和星期,需要使用System.Globalization下的DateTimeFormatInfo类
4 System.Globalization.DateTimeFormatInfo dtInfo = new System.Globalization.CultureInfo("en-US", false).DateTimeFormat;
5 string s = string.Format(dtInfo, "{0:yyyy-MM-dd HH:mm:ss ddd(dddd),MMM(MMMM)}", dt);
6 Console.WriteLine(s);
7Console.ReadLine();
结果:
2009年12月25日 12:30:40 五(星期五),十二月(十二月)
2009-12-25 12:30:40 Fri(Friday),Dec(December)
异常类:
Exception:所有异常对象的基类。
SystemException:运行时产生的所有错误的基类。
IndexOutOfRangeException:当一个数组的下标超出范围时运行时引发。
NullReferenceException:当一个空对象被引用时运行时引发。
InvalidOperationException:当对方法的调用对对象的当前状态无效时,由某些方法引发。
ArgumentException:所有参数异常的基类。
ArgumentNullException:在参数为空(不允许)的情况下,由方法引发。
ArgumentOutOfRangeException:当参数不在一个给定范围之内时,由方法引发。
InteropException:目标在或发生在CLR外面环境中的异常的基类。
ComException:包含COM类的HRESULT信息的异常。
SEHException:封装Win32结构异常处理信息的异常。
SqlException:封装了SQL操作异常。
常见具体的异常对象:
ArgumentNullException 一个空参数传递给方法,该方法不能接受该参数
ArgumentOutOfRangeException 参数值超出范围
ArithmeticException 出现算术上溢或者下溢
ArrayTypeMismatchException 试图在数组中存储错误类型的对象
BadImageFormatException 图形的格式错误
DivideByZeroException 除零异常
DllNotFoundException 找不到引用的DLL
FormatException 参数格式错误
IndexOutOfRangeException 数组索引超出范围
InvalidCastException 使用无效的类
InvalidOperationException 方法的调用时间错误
NotSupportedException 调用的方法在类中没有实现
NullReferenceException 试图使用一个未分配的引用
OutOfMemoryException 内存空间不够
StackOverflowException 堆栈溢出
浙公网安备 33010602011771号