第三章C#程序设计基础.docx

上传人:b****1 文档编号:2869003 上传时间:2023-05-04 格式:DOCX 页数:46 大小:53.22KB
下载 相关 举报
第三章C#程序设计基础.docx_第1页
第1页 / 共46页
第三章C#程序设计基础.docx_第2页
第2页 / 共46页
第三章C#程序设计基础.docx_第3页
第3页 / 共46页
第三章C#程序设计基础.docx_第4页
第4页 / 共46页
第三章C#程序设计基础.docx_第5页
第5页 / 共46页
第三章C#程序设计基础.docx_第6页
第6页 / 共46页
第三章C#程序设计基础.docx_第7页
第7页 / 共46页
第三章C#程序设计基础.docx_第8页
第8页 / 共46页
第三章C#程序设计基础.docx_第9页
第9页 / 共46页
第三章C#程序设计基础.docx_第10页
第10页 / 共46页
第三章C#程序设计基础.docx_第11页
第11页 / 共46页
第三章C#程序设计基础.docx_第12页
第12页 / 共46页
第三章C#程序设计基础.docx_第13页
第13页 / 共46页
第三章C#程序设计基础.docx_第14页
第14页 / 共46页
第三章C#程序设计基础.docx_第15页
第15页 / 共46页
第三章C#程序设计基础.docx_第16页
第16页 / 共46页
第三章C#程序设计基础.docx_第17页
第17页 / 共46页
第三章C#程序设计基础.docx_第18页
第18页 / 共46页
第三章C#程序设计基础.docx_第19页
第19页 / 共46页
第三章C#程序设计基础.docx_第20页
第20页 / 共46页
亲,该文档总共46页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

第三章C#程序设计基础.docx

《第三章C#程序设计基础.docx》由会员分享,可在线阅读,更多相关《第三章C#程序设计基础.docx(46页珍藏版)》请在冰点文库上搜索。

第三章C#程序设计基础.docx

第三章C#程序设计基础

第三章C#程序设计基础

在深入讨论C#面向对象程序设计之前,首先需要掌握C#语言的基本语法结构。

本章将介绍C#的数据类型、运算符和表达式,以及流程控制语句。

3.1数据类型

数据类型是对客观数据对象的抽象,它将数据和对数据的操作封装为一个整体。

C#语言中的数据类型分为值类型和引用类型两大类。

值类型包括整数、字符、实数、布尔数据等简单值类型,以及结构和枚举两种复合值类型;引用类型包括类、接口、委托和数组。

这些类型在本质上都是面向对象的。

3.1.1C#数据类型

C#语言包含13种数值类型,如表3-1所示。

这些内部类型由C#中的关键字定义,它们可以被任何C#程序使用。

数值类型一词表明这些类型的变量有它们对应的数值。

这不同于引用类型,引用类型变量包含对实际值的引用。

因此,值类型更类似其他一些程序设计语言(如C++)中的数据类型。

表3-1C#的数值类型

类型

含义

bool

布尔逻辑值(true和false)

byte

8位无符号整数

char

字符数据类型

decimal

十进制数值类型

double

双精度浮点类型

float

单精度浮点类型

int

整型

long

长整型

sbyte

8位有符号整数

short

短整型

uint

无符号整型

ulong

无符号长整型

ushort

无符号短整型

C#语言中严格限定了每一种数值类型的取值范围,由于可移植性的需要,C#在这一点上是强制的。

例如:

int类型在所有执行环境中都是相同的,不需要而外编写代码来适应特定的平台。

尽管在某些特定环境中,严格指定数值类型的大小可能导致一些性能的损失,但为使程序具备可移植性,这是非常必要的。

3.1.2整型

C#定义了8中整数类型:

byte、sbyte、short、ushort、int、uint、long、ulong。

它们的位宽度和取值范围如表3-2所示。

表3-2整数类型的位宽度和取值范围

类型

位宽度

取值范围

byte

8

0~255

sbyte

8

-128~127

short

16

-32768~32767

ushort

16

0~65535

int

32

-2147483648~2147483647

uint

32

0~4294967295

long

64

-9223372036854775808~9223372036854775807

ulong

64

0~184********709551615

如上表所示,C#定义了各种整数类型的有符号形式和无符号形式。

有符号整数和无符号整数的不同在于对整数高阶位的处理方式。

对于有符号整数,C#编译器将产生代码,把整数的高阶位作为符号位。

如果符号位为0,那么此数为正数;如果符号位为1,那么此数为负数。

最常用的整数类型是int类型。

int类型的变量通常在控制循环、索引数组和常见的整数运算中。

但当整数的取值范围超出int类型的取值范围时,可以有多种选择。

如果要存储的是无符号数,可以是uint类型;对于数值较大的有符号数可以使用long类型;对于取值更大的无符号数可以使用ulong类型。

3.1.3浮点类型

浮点类型可以表示带有小数部分的数据。

浮点类型有两种:

float和double,分别表示单精度数和双精度数。

float类型的宽度为32位,其取值范围大约是1.5E-324~1.7E+308,而double类型的宽度为64位,取值范围大约为5E-324~1.7E+308。

例如:

编写程序计算圆的面积。

//P3-1

usingSystem;

namespaceP3_1

{

classGetArea

{

publicstaticvoidMain()

{

doubler;

doublearea;

r=5.0;

area=3.1415926*r*r;

Console.WriteLine(“areaofcircleis:

”+area);

}

}

}

说明:

程序中GetArea、r、area都是标识符。

标识符是为类、对象、变量和方法等指定的名称。

C#中标识符通常是由字母、或者下划线开头,后跟字母、数字或者下划线组成的字符序列。

另外,C#语言是大小写敏感的,例如myvar和Myvar是两个不同的标识符。

关键字不能作为标识符使用,但是在关键字的前面加上@之后就可以作为标识符使用,但是这样做不是一种好的习惯。

C#语言的关键字请参考附录。

3.1.4decimal类型

decimal类型通常用于货币计算,它使用128位来表示1E-28~7.9E+28之间的数值。

众所周知,正常的浮点运算涉及到小数时常引发各种舍入误差。

decimal类型消除了这种误差,并且能够精确地表示28位有效数字。

这种在表示小数时不出现舍入误差的能力,使得它在被用于财务计算时非常有效。

例如,下面的程序是根据购买商品的数量,计算打折后应支付的费用。

usingSystem;

namespaceP3_2

{

classusedecimal

{

publicstaticvoidMain()

{

decimalprice,discount,paymoney;

intnum;

price=19.95m;

discount=0.15M;

num=15;

paymoney=price*num*(1-discount);

Console.WriteLine(“themoneyshouldpayis:

¥”+paymoney);

}

}

}

注意,上例中的小数常量后面有一个m或M,这是必要的,否则这些数将被认为是标准的浮点常量。

3.1.5字符类型

不同于多数其他计算机语言(如C++),C#语言的字符不是8位,而是采用Unicode编码的16位字符类型。

Unicode定义的字符集大到足以表示所有人类语言中出现的字符。

C#中的char类型是无符号的16位类型,其取值范围是0~65535。

可以给字符类型的变量赋值,此时字符值需要用单引号括起来。

例如:

charch;

ch=’A’;

虽然C#的char类型定义为整数类型,但是它不能任意和整数混合使用。

这是因为没有从整数类型到char类型的自动类型转换。

例如,下面的代码是非法的。

charch;

ch=10;//错误

3.1.6布尔类型

布尔类型(bool)表示逻辑值真或假。

C#语言采用保留字true和false来表示真和假。

因此,布尔类型的变量或表达式将只能取这两个值中的一个。

不同于其他计算机语言,C#没有定义布尔类型和整型之间的转换。

例如,1不能转换为true,0不能转换为false。

例如,下面的程序演示了布尔数据的使用。

usingSystem;

namespaceP3_3

{

classusebool

{

publicstaticvoidMain()

{

boolb=false;

Console.WriteLine(b);

b=true;

Console.WriteLine(b);

Console.WriteLine(10>15);

}

}

}

3.1.7输出格式控制

到目前为止,当使用WriteLine输出数据时,数据总是以默认的格式显示输出。

但是,C#语言提供了一种复杂的格式控制机制,允许用户自定义数据的显示方式。

本书后面将会讨论格式化的I/O,这里先简单介绍一些格式化的常用选项。

使用这些选项,将能够指定WriteLine的输出格式,从而产生更令人满意的结果。

当一个WriteLine语句要输出多个数据项时,用“+”将各个数据项连接起来,如下所示。

Console.WriteLine(“youordered”+2+“itemsat$”+3+“each”);

Console.WriteLine(“Hereis10/3”+10.0/3.0);

虽然,上面的方式使用很方便,但是不能控制数值的输出精度和小数位数。

要控制数字数据的格式,需要使用WriteLine语句的第二种形式,它允许嵌入格式化信息,如下所示:

WriteLine(“formatstring”,arg0,arg1,arg2,…,argn);

这种形式中,WriteLine的参数由逗号隔开,而不是“+”。

格式化字符串(formatstring)包含两项内容:

规则和格式说明符。

格式说明符采用如下的基本形式:

{argnum,width:

fmt}

其中,argnum中指定要显示的参数个数(从0开始)。

width中指定字段的最小宽度,fmt中指定格式。

执行过程中,当在格式字符串中出现格式说明符时,argnum中的数字指定了相应的参数argnum所在位置由所对应的参数取代,即格式说明符定义了参数显示位置。

width和fmt都是可选项。

因此,在其最简形式中,格式说明符只简单地表明显示哪个参数。

例如{0}表示arg0,{1}表示arg1。

例如:

Console.WriteLine(“Februaryhas{0}or{1}days.”,28,29);

输出结果是:

Februaryhas28or29days.

下面给出指定了最小字段宽度的示例:

Console.WriteLine(“Februaryhas{0,5}or{1,10}days.”,28,29);

输出结果是:

Februaryhas28or29days.

从上面的输出可以看到,这里使用空格来确保输出达到最小字段的宽度。

如果实际输出的数值大于指定的最小宽度,则按实际的宽度输出。

下面给出使用格式说明符fmt的例子:

Console.WriteLine(“Hereis10/3:

{0:

#.##}”,10.0/3.0);

输出如下:

Hereis10/3:

3.33

本例中的#.##,是控制输出小数时只输出两位小数。

又如:

Console.WriteLine(“{0:

###,###.##}”,123456.567);

输出如下:

123,456.57

如果要用美元和美分的格式显示数值,则可以使用C格式说明符,例如:

decimalbalance;

balance=12323.09m;

Console.WriteLine(“Currencebalanceis{0:

C}”,balance);

输出结果是:

Currencebalanceis$12,323.09

3.1.8直接量

C#中,直接量是指以固定格式表示的固定数值。

例如,常数100是一个直接量。

直接量通常也称为常量。

C#中的常量可以是任意数值类型的,每种不同类型的常量有不同的表示方式。

下面进行说明。

字符常量是用单引号括起来的单个字符。

例如,’A’,’%’,’a’。

整数常量是不包含小数部分的数。

例如,10,0,-100等。

浮点常量是带小数点的数。

例如,11.23,-96.3,0.0等。

由于C#是一种强类型语言,所以直接量也有类型。

自然地,这也会引入如下问题:

数字直接量的类型是什么?

例如,1212311或者0.23的类型是什么?

幸运的是,C#给出了一些易于理解的规则来解决这些问题。

第一,对于整数直接量,直接量的类型取能保存该数值的最小整数类型即可,首先考虑的是int类型。

类型的取值范围由小到大依次是:

int、uint、long、ulong,具体类型要由数值所属的范围决定。

第二,浮点数直接量的类型统一为double类型。

对于直接量,如果想改变C#默认的类型,可以通过附加后缀来显示地指定其类型。

如要指定long类型的直接量,加上后缀l或L。

例如,12是int类型,12L则是long类型。

要指定无符号整数,则加上会长u或U,例如,100是int类型,而100U是uint类型。

要指定无符号长整型,使用ul或UL,例如,456UL是无符号长整型。

要指定float类型直接量,则在常量后加上f或F,例如,10.19F。

要指定decimal类型的直接常量,则加上后缀m或M。

例如,89.6m。

注意,虽然整数常量默认创建为int、uint、long、ulong类型,但是可以将它们赋值给byte、sbyte、short或ushort类型的变量,只要所赋的值能表示成目标类型即可。

1.转义字符

用单引号表示的字符常量对于大部分可打印字符是有效的,但是对于一些非打印字符,如回车、水平制表符、退格符等,使用文本编辑器时就会有问题出现。

此外,一些其他字符,如单引号、双引号,在C#中有特殊用途,所以不能直接使用它们。

由于这些原因,C#提供了特殊的转义字符,如表3-3所示。

这些序列可以表示它们所代表的非打印字符。

表3-3转义字符序列

转义字符

含义

\a

响铃

\b

退格

\f

换页

\n

换行

\r

回车

\t

水平制表符

\v

垂直制表符

\0

空字符

\’

单引号

\’’

双引号

\\

反斜杠

2.字符串常量

C#支持令一种类型的直接量:

字符串类型。

字符串(string)是用双引号包含的字符序列。

例如,“thisisatest”。

除了常规字符,字符串中也可以包含转义字符。

例如:

usingSystem;

namespaceP3_4

{

classStrDemo

{

publicstaticvoidMain()

{

Console.WriteLine(“Lineone\nLinetow\nLinethree”);

Console.WriteLine(“one\ttow\bthree”);

Console.WriteLine(“\”OK\”\n”);

}

}

}

程序的输出如下:

Lineone

Linetwo

Linethree

onetothree

“OK”

除了上面介绍的字符串常量,还可以指定逐字符字符串常量。

逐字符字符串常量以@开头,后面是由引号包含的字符串。

加引号的字符串的内容被原样输出,而且它们能跨越两行或多行。

因此,可以加入新行、制表符等,但不需要使用转义字符。

唯一例外的是,要显示双引号必须在同一行中使用两个双引号。

下面的程序演示了逐字符字符串常量的使用。

usingSystem;

namespaceP3_5

{

classStrDemo

{

publicstaticvoidMain()

{

Console.WriteLine(@"Thisisaverbatim

stringliteral

thatspansseverallines.");

Console.WriteLine(@"Hesaid:

""Yes""");

}

}

}

程序的运行结果如下:

Thisisaverbatim

stringliteral

thatspansseverallines.

Hesaid:

"Yes"

上面的程序中,需要注意的一点是:

逐字符字符串常量完全按它们的输入顺序显示。

逐字符字符串常量的优点是,可以在程序中直接输入想要在屏幕上显示的内容。

注意,在多行字符串情况下,封装使得程序的缩进被屏蔽。

注意,不要将字符串和字符相混淆。

用单引号括起来的是字符常量,用双引号括起来的是字符串常量。

3.1.9变量

变量是指在程序的运行过程中其值可以被改变的量。

其声明形式如下:

typevar-name;

这里type是变量的数据类型,var-name是变量名。

可以声明任何合法类型的变量。

当创建变量时,实际上是创建变量类型的一个实例。

变量的命名必须符合C#中标识符的命名规则。

C#中所有变量在使用之前必须先声明。

这一点很重要,因为编译器在正确编译使用了变量的语句之前,必须知道变量将包含什么类型的数据,能进行什么样的操作。

这也使得C#能进行严格的类型检查。

在使用变量之前,必须给它赋一个值。

给变量赋值有两种方式:

一种方式是先声明变量,然后用赋值语句给它赋值;另一种方式是在声明变量的同时给变量赋值。

变量初始化的基本形式如下:

typevar=value;

其中value是给变量var指定的初始值。

这个值必须与变量的类型type要求的值相兼容。

例如:

intcount=10;

charch=’x’,ch2=’\0’;

floatf=1.2F;

当声明两个以上相同类型的变量时,变量之间用逗号隔开,且可以为这些变量分别指定初始值。

例如:

inta=0,b,c=12;

本例中a和c被初始化了,b没有初始化。

3.1.10变量的作用域和生存期

到目前为止,我们所使用的变量都是在Main方法的开始处声明的。

然而,C#允许在任意代码块中声明变量。

代码块是用一对大括号“{}”括起来的。

代码块中定义了声明空间,即作用域。

因此,每次开始一个新代码块,就是在创建一个新的作用域。

作用域决定了哪些对象对程序的其他部分是可见的,也决定了这些对象的生命周期。

C#中最重要的作用域是类和方法定义的作用域。

本书将在后面有关类的章节讨论类作用域,这里首先讨论方法定义的作用域。

方法定义的作用域以左大括号“{”开始,以右大括号“}”结束。

然而如果方法中带有参数,那么它们也被包含在方法的作用域中。

通常,定义在作用域内的变量对作用域之外的代码是不可见的(即不可访问)。

因此,当在作用域内声明变量时,就是将变量局部化并防止XX的的访问。

实际上,作用域规则提供了封装性的基础。

作用域可以嵌套。

例如,每次创建一个代码块,就是在创建一个新的、嵌套的作用域。

此时,外层作用域包含内层作用域。

这意味着外层作用域中声明了对象对内层作用域中的代码是可见的(即内层代码可以访问外层代码中声明的对象)。

反之则不成立,内层作用域声明的对象对外层作用域是不可见的。

请看下面的程序:

usingSystem;

namespaceP3_6

{

classscopedemo

{

publicstaticvoidMain()

{

intx;

x=10;

if(x==10)

{

inty=20;

x=y*2;

}

y=100;//error,在外层作用域,内层作用域定义的对象不可见。

Console.WriteLine(“xis:

”+x);

}

}

}

上面的例子中,变量x在Main方法作用的开始处声明的,Main方法中所有代码都能访问它。

y是在if代码块中声明的。

由于代码块定义作用域,因此y只对该代码块中的其他代码可见。

在代码块中变量可以在任意位置声明,但变量只能在声明后才能被使用。

因此,如果在方法开头声明变量,那么它对该方法内的所有代码可见。

反之,如果在代码快末尾声明变量,则该变量实际上是无意义的,因为没有任何代码可以访问它。

另外要记住,进入变量所在的作用域,变量被创建;离开相应的作用域,变量自动释放空间。

这意味着,一旦变量离开其作用域,它就不再保存相应的值。

因此,在同一个方法的不同代码块之间,方法内声明的变量对应不同的值。

同样,离开代码块时,该代码块内声明的变量保存的值将丢失。

因此,变量的声明周期被限制在其作用域内。

C#的作用域规则还有一点需要注意:

虽然代码块可以嵌套,但是内层作用域中声明的变量不能和外层作用域中声明的变量同名(这和C、C++不同)。

例如:

usingSystem;

namespaceP3_7

{

classnestscope

{

publicstaticvoidMain()

{

intcount;

for(count=0;count<10;count++)

{

Console.WriteLine(“Thisiscount:

”+count);

intcount;//错误,不能和外层作用域中的变量同名。

Console.WriteLine(count);//这里使用的是外层作用域定义的count。

}

}

}

}

3.1.11类型转换

在程序设计中,将一种类型的数据赋值给另一种类型的变量是很普遍的。

例如将一个整型数据赋值给一个float类型的变量,如下所示:

inti;

floatf;

i=10;

f=i;//将整型值赋值给float类型的变量f。

当赋值语句中出现了相互兼容的类型时,等式右边的类型将自动转换为等式左边的类型。

因此,在前面的代码片断中,变量i中的值将转换为float类型,并赋值给变量f。

然而,因为C#的严格类型检查,所以并不是所有的类型都是兼容的,因此,不是所有的类型转换都可以隐式地进行。

例如,bool类型和int类型是不兼容的。

幸运的是,还可以通过强制类型转换(cast)在不兼容的类型之间进行转换。

1.自动类型转换

当一种类型的数据赋值给另一种类型的变量时,如果满足下列条件,则进行自动类型转换。

●两种类型是兼容的。

●目标类型比源类型的取值范围大。

当满足这两个条件时,将进行扩展转换(wideningconversion)。

例如,int类型变量足以保存所有byte类型的值,而且int类型和byte类型都是整型数据,所以将byte类型的值赋值给int类型变量时将进行自动转换。

对于扩展类型转换,数字类型(包括整型数据和浮点数据)都是相互兼容的。

例如:

usingSystem;

namespaceP3_8

{

classLtoD

{

publicstaticvoidMain()

{

longl;

doubled;

l=10012356L;

d=l;//这是扩展转换

Console.WriteLine(“LandD:

”+l+””+d);

}

}

}

虽然可以将long类型赋值给double类型,但是反过来却不行,因为这不是扩展转换。

另外,也不存在decimal类型到float类型或到double类型的转换,以及从数字类型到char类型或到bool类型的转换。

同样char类型和bool类型也不是相互兼容的。

2.强制类型转换

虽然自动类型转换非常有用,但是它们不能满足所有程序设计的需要,因为它们只能在相互兼容的类型之间进行扩展转换。

对于其他的所有情况,必须使用强制类型转换。

强制类型转换(cast)是一种指令,命令编译器将一种类型转换为另一种类型。

因此,它需要显式地进行。

强制类型转换的基本形式如下:

(target-type)expression

其中,target-type是转换的目标类型,expression是待转换的表达式。

例如:

doublex=23.6,y=3.5;

inti=(int)(x/y);//将x/y的商强制转换为int类型,然后赋值给变量i。

当强制类型转换涉及到收缩转换时,可能丢失信息。

例如,将long类型强制转换成int类型时,如果long类型的变量的值超出int类型变量的取值范围,将丢失信息,因为高阶位的值被消除了。

当浮点类型的值强制转换为整型时,由于截断的原因小数部分丢失。

下面的例子演示了强制类型转换,也给出了一些由于强制类型转换引起数据丢失的情况。

usingSystem;

namespaceP3_9

{

classcastdemo

{

publicstaticvoidMain()

{

doublex,y;

byteb;

inti;

charch;

uintu;

shorts;

longl;

x=10.0;

y=3.0;

//castdoubleint

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > 其它考试

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2