《第三章-C#程序设计基础(共27页).doc》由会员分享,可在线阅读,更多相关《第三章-C#程序设计基础(共27页).doc(27页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上第三章 C#程序设计基础在深入讨论C#面向对象程序设计之前,首先需要掌握C#语言的基本语法结构。本章将介绍C#的数据类型、运算符和表达式,以及流程控制语句。3.1 数据类型数据类型是对客观数据对象的抽象,它将数据和对数据的操作封装为一个整体。C#语言中的数据类型分为值类型和引用类型两大类。值类型包括整数、字符、实数、布尔数据等简单值类型,以及结构和枚举两种复合值类型;引用类型包括类、接口、委托和数组。这些类型在本质上都是面向对象的。3.1.1 C#数据类型C#语言包含13种数值类型,如表3-1所示。这些内部类型由C#中的关键字定义,它们可以被任何C#程序使用。数值类型
2、一词表明这些类型的变量有它们对应的数值。这不同于引用类型,引用类型变量包含对实际值的引用。因此,值类型更类似其他一些程序设计语言(如C+)中的数据类型。表3-1 C#的数值类型类型含义bool布尔逻辑值(true和false)byte8位无符号整数char字符数据类型decimal十进制数值类型double双精度浮点类型float单精度浮点类型int整型long长整型sbyte8位有符号整数short短整型uint无符号整型ulong无符号长整型ushort无符号短整型C#语言中严格限定了每一种数值类型的取值范围,由于可移植性的需要,C#在这一点上是强制的。例如:int类型在所有执行环境中都是
3、相同的,不需要而外编写代码来适应特定的平台。尽管在某些特定环境中,严格指定数值类型的大小可能导致一些性能的损失,但为使程序具备可移植性,这是非常必要的。3.1.2 整型C#定义了8中整数类型:byte、sbyte、short、ushort、int、uint、long、ulong。它们的位宽度和取值范围如表3-2所示。表3-2 整数类型的位宽度和取值范围类型位宽度取值范围byte80255sbyte8-128127short16-3276832767ushort16065535int32-uint320long64-ulong640如上表所示,C#定义了各种整数类型的有符号形式和无符号形式。有符
4、号整数和无符号整数的不同在于对整数高阶位的处理方式。对于有符号整数,C#编译器将产生代码,把整数的高阶位作为符号位。如果符号位为0,那么此数为正数;如果符号位为1,那么此数为负数。最常用的整数类型是int类型。int类型的变量通常在控制循环、索引数组和常见的整数运算中。但当整数的取值范围超出int类型的取值范围时,可以有多种选择。如果要存储的是无符号数,可以是uint类型;对于数值较大的有符号数可以使用long类型;对于取值更大的无符号数可以使用ulong类型。3.1.3 浮点类型浮点类型可以表示带有小数部分的数据。浮点类型有两种:float和double,分别表示单精度数和双精度数。floa
5、t类型的宽度为32位,其取值范围大约是1.5E-3241.7E+308,而double类型的宽度为64位,取值范围大约为5E-3241.7E+308。例如:编写程序计算圆的面积。/P3-1using System;namespace P3_1class GetAreapublic static void Main()double r;double area;r=5.0;area=3.*r*r;Console.WriteLine(“area of circle is :”+area);说明:程序中GetArea、r、area都是标识符。标识符是为类、对象、变量和方法等指定的名称。C#中标识符通常
6、是由字母、或者下划线开头,后跟字母、数字或者下划线组成的字符序列。另外,C#语言是大小写敏感的,例如myvar和Myvar是两个不同的标识符。关键字不能作为标识符使用,但是在关键字的前面加上之后就可以作为标识符使用,但是这样做不是一种好的习惯。C#语言的关键字请参考附录。3.1.4 decimal类型decimal类型通常用于货币计算,它使用128位来表示1E-287.9E+28之间的数值。众所周知,正常的浮点运算涉及到小数时常引发各种舍入误差。decimal类型消除了这种误差,并且能够精确地表示28位有效数字。这种在表示小数时不出现舍入误差的能力,使得它在被用于财务计算时非常有效。例如,下面
7、的程序是根据购买商品的数量,计算打折后应支付的费用。using System;namespace P3_2class usedecimalpublic static void Main()decimal price,discount,paymoney;int num;price=19.95m;discount=0.15M;num=15;paymoney=price*num*(1-discount);Console.WriteLine(“the money should pay is :¥”+paymoney);注意,上例中的小数常量后面有一个m或M,这是必要的,否则这些数将被认为是标准的浮点常
8、量。3.1.5 字符类型不同于多数其他计算机语言(如C+),C#语言的字符不是8位,而是采用Unicode编码的16位字符类型。Unicode定义的字符集大到足以表示所有人类语言中出现的字符。C#中的char类型是无符号的16位类型,其取值范围是065535。可以给字符类型的变量赋值,此时字符值需要用单引号括起来。例如:char ch;ch=A;虽然C#的char类型定义为整数类型,但是它不能任意和整数混合使用。这是因为没有从整数类型到char类型的自动类型转换。例如,下面的代码是非法的。char ch;ch=10;/错误3.1.6 布尔类型布尔类型(bool)表示逻辑值真或假。C#语言采用保
9、留字true和false来表示真和假。因此,布尔类型的变量或表达式将只能取这两个值中的一个。不同于其他计算机语言,C#没有定义布尔类型和整型之间的转换。例如,1不能转换为true,0不能转换为false。例如,下面的程序演示了布尔数据的使用。using System;namespace P3_3class useboolpublic static void Main()bool b=false;Console.WriteLine(b);b=true;Console.WriteLine(b);Console.WriteLine(1015);3.1.7 输出格式控制到目前为止,当使用WriteLi
10、ne输出数据时,数据总是以默认的格式显示输出。但是,C#语言提供了一种复杂的格式控制机制,允许用户自定义数据的显示方式。本书后面将会讨论格式化的I/O,这里先简单介绍一些格式化的常用选项。使用这些选项,将能够指定WriteLine的输出格式,从而产生更令人满意的结果。当一个WriteLine语句要输出多个数据项时,用“+”将各个数据项连接起来,如下所示。Console.WriteLine(“you ordered”+2+“ items at $”+3+“ each”);Console.WriteLine(“Here is 10/3”+10.0/3.0);虽然,上面的方式使用很方便,但是不能控制
11、数值的输出精度和小数位数。要控制数字数据的格式,需要使用WriteLine语句的第二种形式,它允许嵌入格式化信息,如下所示:WriteLine(“format string”,arg0,arg1,arg2,argn);这种形式中,WriteLine的参数由逗号隔开,而不是“+”。格式化字符串(format string)包含两项内容:规则和格式说明符。格式说明符采用如下的基本形式:argnum,width:fmt其中,argnum中指定要显示的参数个数(从0开始)。width中指定字段的最小宽度,fmt中指定格式。执行过程中,当在格式字符串中出现格式说明符时,argnum中的数字指定了相应的参
12、数argnum所在位置由所对应的参数取代,即格式说明符定义了参数显示位置。width和fmt都是可选项。因此,在其最简形式中,格式说明符只简单地表明显示哪个参数。例如0表示arg0,1表示arg1。例如:Console.WriteLine(“February has 0 or 1 days.”,28,29);输出结果是:February has 28 or 29 days.下面给出指定了最小字段宽度的示例:Console.WriteLine(“February has 0,5 or 1,10 days.”,28,29);输出结果是:February has 28 or 29 days.从上面的
13、输出可以看到,这里使用空格来确保输出达到最小字段的宽度。如果实际输出的数值大于指定的最小宽度,则按实际的宽度输出。下面给出使用格式说明符fmt的例子:Console.WriteLine(“Here is 10/3:0:#.#”,10.0/3.0);输出如下:Here is 10/3:3.33本例中的#.#,是控制输出小数时只输出两位小数。又如:Console.WriteLine(“0:#,#.#”,.567);输出如下:123,456.57如果要用美元和美分的格式显示数值,则可以使用C格式说明符,例如:decimal balance;balance=12323.09m;Console.Writ
14、eLine(“Currence balance is 0:C”,balance);输出结果是:Currence balance is $12,323.093.1.8 直接量C#中,直接量是指以固定格式表示的固定数值。例如,常数100是一个直接量。直接量通常也称为常量。C#中的常量可以是任意数值类型的,每种不同类型的常量有不同的表示方式。下面进行说明。字符常量是用单引号括起来的单个字符。例如,A,%,a。整数常量是不包含小数部分的数。例如,10,0,-100等。浮点常量是带小数点的数。例如,11.23,-96.3,0.0等。由于C#是一种强类型语言,所以直接量也有类型。自然地,这也会引入如下问题
15、:数字直接量的类型是什么?例如,或者0.23的类型是什么?幸运的是,C#给出了一些易于理解的规则来解决这些问题。第一,对于整数直接量,直接量的类型取能保存该数值的最小整数类型即可,首先考虑的是int类型。类型的取值范围由小到大依次是:int、uint、long、ulong,具体类型要由数值所属的范围决定。第二,浮点数直接量的类型统一为double类型。对于直接量,如果想改变C#默认的类型,可以通过附加后缀来显示地指定其类型。如要指定long类型的直接量,加上后缀l或L。例如,12是int类型,12L则是long类型。要指定无符号整数,则加上会长u或U,例如,100是int类型,而100U是ui
16、nt类型。要指定无符号长整型,使用ul或UL,例如,456UL是无符号长整型。要指定float类型直接量,则在常量后加上f或F,例如,10.19F。要指定decimal类型的直接常量,则加上后缀m或M。例如,89.6m。注意,虽然整数常量默认创建为int、uint、long、ulong类型,但是可以将它们赋值给byte、sbyte、short或ushort类型的变量,只要所赋的值能表示成目标类型即可。1.转义字符用单引号表示的字符常量对于大部分可打印字符是有效的,但是对于一些非打印字符,如回车、水平制表符、退格符等,使用文本编辑器时就会有问题出现。此外,一些其他字符,如单引号、双引号,在C#中
17、有特殊用途,所以不能直接使用它们。由于这些原因,C#提供了特殊的转义字符,如表3-3所示。这些序列可以表示它们所代表的非打印字符。表3-3 转义字符序列转义字符含义a响铃b退格f换页n换行r回车t水平制表符v垂直制表符0空字符单引号双引号反斜杠2.字符串常量C#支持令一种类型的直接量:字符串类型。字符串(string)是用双引号包含的字符序列。例如,“this is a test”。除了常规字符,字符串中也可以包含转义字符。例如:using System;namespace P3_4class StrDemopublic static void Main()Console.WriteLine(
18、“Line onenLine townLine three”);Console.WriteLine(“onettowbthree”);Console.WriteLine(“”OK”n”);程序的输出如下:Line oneLine twoLine threeone tothree“OK”除了上面介绍的字符串常量,还可以指定逐字符字符串常量。逐字符字符串常量以开头,后面是由引号包含的字符串。加引号的字符串的内容被原样输出,而且它们能跨越两行或多行。因此,可以加入新行、制表符等,但不需要使用转义字符。唯一例外的是,要显示双引号必须在同一行中使用两个双引号。下面的程序演示了逐字符字符串常量的使用。us
19、ing System;namespace P3_5 class StrDemo public static void Main() Console.WriteLine(This is a verbatimstring literalthat spans several lines.); Console.WriteLine(He said:Yes); 程序的运行结果如下:This is a verbatimstring literalthat spans several lines.He said: Yes上面的程序中,需要注意的一点是:逐字符字符串常量完全按它们的输入顺序显示。逐字符字符串常量
20、的优点是,可以在程序中直接输入想要在屏幕上显示的内容。注意,在多行字符串情况下,封装使得程序的缩进被屏蔽。注意,不要将字符串和字符相混淆。用单引号括起来的是字符常量,用双引号括起来的是字符串常量。3.1.9 变量变量是指在程序的运行过程中其值可以被改变的量。其声明形式如下:type var-name;这里type是变量的数据类型,var-name是变量名。可以声明任何合法类型的变量。当创建变量时,实际上是创建变量类型的一个实例。变量的命名必须符合C#中标识符的命名规则。C#中所有变量在使用之前必须先声明。这一点很重要,因为编译器在正确编译使用了变量的语句之前,必须知道变量将包含什么类型的数据,
21、能进行什么样的操作。这也使得C#能进行严格的类型检查。在使用变量之前,必须给它赋一个值。给变量赋值有两种方式:一种方式是先声明变量,然后用赋值语句给它赋值;另一种方式是在声明变量的同时给变量赋值。变量初始化的基本形式如下:type var=value;其中value是给变量var指定的初始值。这个值必须与变量的类型type要求的值相兼容。例如:int count=10;char ch=x,ch2=0;float f=1.2F;当声明两个以上相同类型的变量时,变量之间用逗号隔开,且可以为这些变量分别指定初始值。例如:int a=0,b,c=12;本例中a和c被初始化了,b没有初始化。3.1.10
22、 变量的作用域和生存期到目前为止,我们所使用的变量都是在Main方法的开始处声明的。然而,C#允许在任意代码块中声明变量。代码块是用一对大括号“”括起来的。代码块中定义了声明空间,即作用域。因此,每次开始一个新代码块,就是在创建一个新的作用域。作用域决定了哪些对象对程序的其他部分是可见的,也决定了这些对象的生命周期。C#中最重要的作用域是类和方法定义的作用域。本书将在后面有关类的章节讨论类作用域,这里首先讨论方法定义的作用域。方法定义的作用域以左大括号“”开始,以右大括号“”结束。然而如果方法中带有参数,那么它们也被包含在方法的作用域中。通常,定义在作用域内的变量对作用域之外的代码是不可见的(
23、即不可访问)。因此,当在作用域内声明变量时,就是将变量局部化并防止未经授权的的访问。实际上,作用域规则提供了封装性的基础。作用域可以嵌套。例如,每次创建一个代码块,就是在创建一个新的、嵌套的作用域。此时,外层作用域包含内层作用域。这意味着外层作用域中声明了对象对内层作用域中的代码是可见的(即内层代码可以访问外层代码中声明的对象)。反之则不成立,内层作用域声明的对象对外层作用域是不可见的。请看下面的程序:using System;namespace P3_6class scopedemopublic static void Main()int x;x=10;if(x=10)int y=20;x=
24、y*2;y=100;/error,在外层作用域,内层作用域定义的对象不可见。Console.WriteLine(“x is:”+x);上面的例子中,变量x在Main方法作用的开始处声明的,Main方法中所有代码都能访问它。y是在if代码块中声明的。由于代码块定义作用域,因此y只对该代码块中的其他代码可见。在代码块中变量可以在任意位置声明,但变量只能在声明后才能被使用。因此,如果在方法开头声明变量,那么它对该方法内的所有代码可见。反之,如果在代码快末尾声明变量,则该变量实际上是无意义的,因为没有任何代码可以访问它。另外要记住,进入变量所在的作用域,变量被创建;离开相应的作用域,变量自动释放空间。
25、这意味着,一旦变量离开其作用域,它就不再保存相应的值。因此,在同一个方法的不同代码块之间,方法内声明的变量对应不同的值。同样,离开代码块时,该代码块内声明的变量保存的值将丢失。因此,变量的声明周期被限制在其作用域内。C#的作用域规则还有一点需要注意:虽然代码块可以嵌套,但是内层作用域中声明的变量不能和外层作用域中声明的变量同名(这和C、C+不同)。例如:using System;namespace P3_7class nestscopepublic static void Main()int count;for(count=0;count大于=大于等于=小于等于C#还有一个特殊的关系运算符“i
26、s”,它用于判断左操作数的类型是否为右操作数,例如:int x=5;object obj=x;Console.WriteLine(obj is object);/输出trueConsole.WriteLine(obj is int);/输出trueConsole.WriteLine(obj is long);/输出false操作符“is”主要用于引用类型的判断,只要左操作数的类型为右操作数或是右操作数的派生类类型,表达式就返回true。不过如果左操作数为null,则始终返回false。3.2.3 逻辑运算符C#定义的逻辑运算符如表3-6所示。其中,逻辑与和逻辑或要求有两个操作数,而逻辑非只有一
27、个操作数。它们的真值表如表3-7所示。在逻辑表达式的求值过程中,有时不需要计算完整个表达式就可以得到结果,这称为逻辑表达式的短路效应。例如,下面的表达式是用于判断一个年份是否为闰年。bool leapyear=(year%400=0)|(year%4=0)&(year%100!=0);对于上面的代码,当year为2000时,第一对括号中的条件表达式的值为true,那么leapyear的值就直接确定为true了,而不需要再计算操作符|之后的部分。表3-6 逻辑运算符运算符含义&逻辑与|逻辑或!逻辑非表3-7 逻辑运算真值表PQP&QP|Q!Pfalsefalsefalse falsetruefa
28、lsetruefalsetruetruetruefalsefalsetruefalsetruetruetruetruefalse3.2.4 赋值运算符C#中赋值运算符是=,它是一个二元运算符,其功能是将右操作数的值赋值给左操作数(左操作数通常是变量),前提条件是右操作数的类型必须与左操作数类型相同,或可以隐式转换为左操作数的类型。为了简化程序代码,C#还提供了10个复合赋值运算符+=、-=、*=、/=、%=、=、&=、|=、=,它们实际上是将加、减、乘、除、取模、算术左移、算术右移、按位于、按位或、按位异或这些运算和简单赋值运算结合起来。例如,x+=y,等价于x=x+y。和一般的算术运算符不同
29、,赋值运算符属于右结合操作符,即表达式会按照从右到左的顺序进行赋值运算。例如:int x=10,y=10;int z=y*=x*=10; /先计算x*=10,再计算y*=x,最后执行z=y赋值运算符在所有运算符中优先级最低,即表达式总是先计算赋值符号右边的部分,再进行赋值运算。例如,表达式x+=y+z,会先计算y与z的和,然后再将其加上x,最后赋值给x,即上面的表达式等价于x=x+(y+z)。3.2.5 位运算符C#定义的位运算符如表3-8所示,它们是对数据按二进制位进行运算的操作符。下面分别介绍。l 按位取反运算符“”:作用于一个操作数,且必须放在操作数的前面,表示对操作数的个二进制位取反。l 按位与运算符“&”:作用于两个操作数,表示对两个操作数的对应二进制位进行与运算。l 按位或运算符“|”:作用于两个操作数,表示对两个操作数的对应二进制位进行或运算。l 按位异或运算符“”:作用于两个操作数,表示对两个操作数的对应二进制位进行异或运算。l 算术左移运算“”:作用于两个操作数,表示将左操作数的各二进制位依次右移,右边的低位被舍弃,左边的高位对正数补0,负数补1,移动的位数由右操作数确定。表3-8 位运算符运算符含义&按位与|按位或按位取反按位异或算术右移算术左移按位取反运算符的优先级高于算术运算符,其他位运算符的优先级则低于算术运算符