面向对象组件的C编程科学出版社

上传人:汽*** 文档编号:570170385 上传时间:2024-08-02 格式:PPT 页数:71 大小:1.41MB
返回 下载 相关 举报
面向对象组件的C编程科学出版社_第1页
第1页 / 共71页
面向对象组件的C编程科学出版社_第2页
第2页 / 共71页
面向对象组件的C编程科学出版社_第3页
第3页 / 共71页
面向对象组件的C编程科学出版社_第4页
第4页 / 共71页
面向对象组件的C编程科学出版社_第5页
第5页 / 共71页
点击查看更多>>
资源描述

《面向对象组件的C编程科学出版社》由会员分享,可在线阅读,更多相关《面向对象组件的C编程科学出版社(71页珍藏版)》请在金锄头文库上搜索。

1、面向对象和组件的C#编程科学出版社第二章第二章 程序结构、变量、类型、运算符程序结构、变量、类型、运算符李军武汉大学测绘学院“我成长”网站第二章第二章 程序结构、变量、类型、运算符程序结构、变量、类型、运算符1234 程序结构程序结构变量、常量和字量变量、常量和字量类型类型运算符运算符5运算符的优先级和结合性运算符的优先级和结合性2.1 程序结构程序结构在1.7节,我们编写了一个Hello控制台程序,代码如下。usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceHelloA

2、ppclassProgramstaticvoidMain(stringargs)Console.WriteLine(Hello!);最简单的最简单的Hello控制台程序代码控制台程序代码上面就是最简单的Hello控制台程序代码吗?其实代码还可简化成下面的形式:classProgramstaticvoidMain()System.Console.WriteLine(Hello!);它没有了前面四条using语句,也没有了namespace,Main()中也没有参数;但在Console前添加了“System.”。它才是最简单的Hello控制台程序代码!2.1.1 用类比理解程序结构用类比理解程序结

3、构房屋好比是类class,房屋名称为HappyHouse;房屋入口是类中的Main()函数。房主拥有的那块土地称为myLand,它由namesapce定义:namespacemyLandclassHappyHousestaticvoidMain()System.Console.WriteLine(Hello!);类比1)WriteLine可类比为其它土地(System)中房屋(Console)里面的某个东西,用代码表示为:土地.房屋.东西;2)小数点“.”表示访问操作,例如myLand.HappyHouse.Main()表示:访问myLand中HappyHouse的Main成员。3)Happy

4、House房主并没有定义WriteLine,但并不妨碍他借用别人的东西。他在Main中就借用了基类库BCL的函数:System.Console.WriteLine();2.1.2 命名空间命名空间用C#的术语说,namespace关键字定义了命名空间,大括号中的东西称为类型,语法如下:namespace空间名称定义类型大括号界定了范围。空间名称要唯一,否则无法界定命名空间中的类型。类型中定义的东西称为成员。如下所示:namespace空间名称类型1成员类型2成员.命名空间-一个分组符号namespace说明HelloApp是本项目的命名空间。命名空间就是一个程序集内相关类型的一个分组符号。 S

5、ystem 内建数据、数学计算、垃圾收集器 System.Drawing 处理图形和绘图,包括打印 System.Data 处理数据存取和管理,ADO.NET System.IO 管理对文件和流的同步和异步访问System.Windows 处理基于窗体的窗口的创建System.Reflection 包含从程序集读取元数据的类System.Threading 包含用于多线程编程的类System.Collections 包含定义各种对象集的接口和类程序集、命名空间、类型和成员一个程序集可以包含任意个命名空间,每个命名空间又可以包含多种类型。用“对象浏览器”可见:程序集只有一个HelloApp命名空

6、间,命名空间中的类型是Program类(class),Object是Program的基类;右边是Object类的成员。分析下面代码namespaceHelloApp/命名空间inta;/定义变量:错误!staticvoidMain()/定义函数:错误!classProgram2.1.3 引用引用using“引用”反映了C#编程的组件思想:尽可能使用基类库或其它成熟的程序集。usingSystem;说明了HelloApp项目引用(using)了System命名空间。System命名空间中,提供了大量核心的类型,如System.Int32、string等类型,定义在内部程序集内部程序集中中。usi

7、ng简化了对特定命名空间中类型的引用方法引用方法。因为引用了System,所以编译器能够将Console类解析为这个命名空间的成员。如果没有引用System,将出现一个编译器错误。也可以使用完全限定名来使用Console类的函数:System.Console.WriteLine(Hello!);系统自动添加的引用-内部程序内部程序集集许多核心的.NET命名空间包含在mscorlib.dll文件中。多数.NETFramework程序集都位于全局程序集缓存GAC的特定目录下(默认下C:WindowsAssembly)。在创建本项目时,系统自动添加了一些全局程序集的引用,对它们的引用,仅仅通过usi

8、ng关键字来指定命名空间即可。引用外部程序集(doit)不在上图中列出的程序集,都是外部程序集。对外部程序集,除了通过using关键字来指定命名空间,还需要告诉C#编译器包含引用类型的程序集的名字。例如,System.Drawing.Bitmap类型包含在另一个名为System.Drawing.dll的程序集中。引用它的方法如下:右键点击【引用】【添加引用】,然后在对话框中选择System.Drawing组件;见下图。添加System.Drawing.dll程序集在Program.cs代码前添加:usingSystem.Drawing;你就可以在项目中添加图形类型的具体引用了,例如在Main(

9、)中加上语句:BitmapMap=newBitmap(20,20);Bitmap是System.Drawing命名空间中的一个类。Map是Bitmap类型的变量,通过Map=newBitmap(20,20);语句被赋值为Bitmap对象;即调用Bitmap类的构造函数Bitmap(20,20)来创建的一个对象。也可说Map是用new实例化的一个Bitmap对象。注:命名空间与程序集一般是对应的,命名空间为*,它的程序集名字就为*.dll。2.1.4 格式化输出格式化输出在Main()中添加语句:Console.WriteLine(0,1,Hello,World!);系统输出:“Hello,Wo

10、rld!”字符串。0、1标记嵌入在字符串中,它是格式化输出方法,与C语言的printf()相似。可以使用这种花括号在文本内部指定占位符。在运行时,值会传入到WriteLine()来替代每一个占位符。数据的位置索引可以在字符串文本的任意位置放置占位符,而不需要按照递增的次序。例如代码:Console.WriteLine(1+0+2=3,10,20,30,60);/数据的位置索引0123/输出:20+10+30=60后面数据10,20,30,60的位置索引总是依递增次序0,1,2,3;而占位符n中的n只能是03,0表明在占位符0上接受的是索引为0的数据(即10),1上接受的是索引为1的数据(即20

11、);而0排在1的后面,故10在20的后面显示。格式化数值数据格式化数值数据如果数值数据需要更精细的格式化,每一个占位符都可以(可选)包含不同的格式字符,下表显示了核心格式化选项。使用一些格式化标记(doit)给定的占位符值以冒号为标记,将这些字符作为后缀(例如,0:C、1:d、2:X)。修改Main()方法,添加下面的语句,从而格式化一个固定值。例如:/使用一些格式化标记Console.WriteLine(Thevalue88888invariousformats:);Console.WriteLine(cformat:0:c,88888);/0代表占位符Console.WriteLine(d

12、9format:0:d9,88888);/补零到9位,前补零Console.WriteLine(f3format:0:f3,88888);/f3保留小数点后3位Console.WriteLine(nformat:0:n,88888);/注意,十六进制数的大小写形式决定了字母是大写还是小写。Console.WriteLine(Eformat:0:E,88888);Console.WriteLine(eformat:0:e,88888);Console.WriteLine(Xformat:0:X,88888);Console.WriteLine(xformat:0:x,88888);应用程序的输出

13、(doit) 在控制台应用程序外格式化数值数据在控制台应用程序外格式化数值数据.NET字符串格式化字符不局限于在控制台程序中使用!同样的格式化语法可以在调用静态的string.Format()方法时使用。如果我们需要对任何应用程序类型(桌面GUI程序、Web程序等)在运行时组合文本数据,这个方法就很有用。在消息对话框中显示:/使用string.Format()来格式化字符串文本stringuserSt=string.Format(100inhexis0:x,100);/需要引用System.Windows.Forms.dll才能编译这行代码System.Windows.Forms.Messag

14、eBox.Show(userSt);注意string.Format()是按照提供的标志进行格式化的。至此,我们就可以任意使用需要的文本数据了。2.2 变量、常量和字量变量、常量和字量2.2.1 变量的声明变量的声明定义或声明变量的方法如下:类型var_name;类型var_name=初值;其中var_name是变量的名称(标识符)。注:如果是在类中定义的变量,声明时可加修饰符(细节见后面章节)2.2.3 变量的种类和赋值变量的种类和赋值2.2.2 变量的命名变量的命名 (自学自学)变量分为八种类别:变量分为八种类别: 静态、非静态变量、数组元素、局部变量静态、非静态变量、数组元素、局部变量,

15、值参数、引用参数、输出参数、数组参数。值参数、引用参数、输出参数、数组参数。注意:在C#中,不能定义全局变量。【例例2-3】变量的种类。变量的种类。classProgram/类intx=1;/x是非静态变量publicstaticinty=2;/y是静态变量voidf(ints,intval,refinti,outintj)/数组s,值参数valintw=2;/w是局部变量j=x+y+i+w;/j是输出参数x是非静态变量,是非静态变量,y是静态变量,是静态变量,s是数组,是数组,val是值参数,是值参数,i是引用参数,是引用参数,j是输出参数。是输出参数。2.2.4 常量和字量常量和字量常量声

16、明的语法为:修饰符const类型ConstName;在声明常量时,要用到const关键字。下面是一个声明常量的例子:publicconstdoublePI=3.1415926;字量字量字量就是类型的字面值。它与常量本质上相同,但它更加简单:不用声明,把值直接写出来即可。例如,下面语句中出现的123就是整数字量:inti=123;字符串字量字符串字量strings3=“HellonWorld!”;/串包含转义序列n,换行Console.WriteLine(0,s3);运行结果:Hello World!逐字字符串字量逐字字符串字量逐字字符串字量由字符和后面双引号中的多个字符组成,如果包含转义序列或

17、Unicode字符,都作为一般字符处理。即“转义”失效。例如:strings1=HelloWorld!;/有字符的串strings2=HellonWorld!;/串包含转义序列n,但作为二个一般字符处理,即:和nConsole.WriteLine(01,s1,s2);运行结果:HelloWorld!HellonWorld!空空字量字量空字量只有一个:null。null本质的含义是没有任何值,即“空”。null不属于任何类型,但它可隐式地转换为任何可接受空值的类型,如引用类型。字符串和object都是引用类型,所以下面语句是正确的:stringst=null;/null不等价于无字符的串obje

18、ctobj=null;/表示obj没有任何值可空类型int?但下面的语句不正确:inti=null;简单类型不是可空类型,所以int类型的变量不接受null因此C#提供了“可空类型”这种语法,只要在任何“不可空”的类型后加?就构成了可空的类型,如“int?”,所以下面语句是正确的:int?i=null;float?f=null;2.3 类型类型计算机科学家Wirth提出过一个公式:算法+数据结构=程序数据结构在.NET中的形式就是公共类型系统,简称类型(Type)。一个变量用于连接一个名称(变量名)和一小块内存。一个变量有它的值,也就是这小块内存中存储的值。至于这小块内存的大小,以及如何解释其

19、中存储的数据,是和变量的类型相关的。整个C#类型系统2.3.1 类型的分类类型的分类1)值类型和引用类型(分类方法)值类型和引用类型(分类方法1)如果按变量存储的是数据还是数据的引用来区分,C#类型(或CTS)可分为值类型和引用类型,见下图。进一步划分进一步划分值类型进一步划分值类型进一步划分:简单类型(simpletype)枚举类型(enumtype)结构类型(structtype)引用类型进一步划分:引用类型进一步划分:类类型(classtype)接口类型(interfacetype)数组类型(arraytype)委托类型(delegatetype)字符串类型(stringtype)代码例

20、子代码例子值类型变量直接包括它们的数据,而引用类型变量存储的是它们的数据引用(即对象引用)。例如:inti=1;/i是值类型变量,1直接存储在i中。objectobj=newobject();obj是引用类型变量,obj存储的是对象的引用。如何理解引用类型如何理解引用类型“引用类型到底是什么东西啊?”我们用比喻法来回答您的问题。计算机的内存是用于存放数据的,所以内存好比是房屋。只有二种房屋:一种是“堆”,另一种是“栈”。但每种房屋会有许多房间,用“房间号”区分它们,“房间号”其实就是内存地址。doublex=12.3;/x是值类型变量,12.3直接存储在x中。doubley=x;/y是值类型变

21、量,y=x导致12.3存储在y中。strings1=newstring(w,3);/s1是引用类型变量,s1存储的是地址0x01-对象的引用。strings2=Hello;/s2存储的是地址0x02对象Hello的引用。strings3;/s3是引用类型变量,s3什么也没有存储。strings4=s2;/s4=s2,导致地址0x02存储在s4中。内建系统类型和自定义类型内建系统类型和自定义类型(分类方法(分类方法2)如果按类型是系统定义好的还是用户自定义的来区分,C#类型可分为内建系统类型和自定义类型。有5种C#类型可由用户自定义:类类型、结构类型、接口类型、枚举类型和委托类型。其它的都是系统

22、内建好的,用户可直接使用。内建系统类型=简单类型+两个引用类型(string和object类)C#内建系统类型CLS的类型注:符合CLS的类型可以被任何托管编程语言使用。如果你的程序中出现了不符合CLS的数据,那么其他语言可能就不能使用它们。上表中,有一列(系统类型)专门给出了每种类型的完整名称。C#的所有基本类型都有一个短名称和一个完整名称。完整名称对应于BCL中命名的类型。这个名称在所有语言中都是相同的。其实从编译器的角度看,两种名称是完全一样的,最终都将生成同样的代码。自定义的值类型(枚举和结构)自定义的值类型(枚举和结构)其它其它“自定义类型自定义类型” 见第见第3章之后的内容章之后的

23、内容1) 枚举枚举枚举类型是一组命名常数的值类型。下面的Color枚举类型有三个命名常数:Red、Green和Blue;它们的值分别为0、1和2。enumColorRed,Green,Blue虽然数值0、1、2代表三种颜色,但用命名(Red、Green、Blue)显然要好些,名称更好记忆与理解。这正是我们用枚举的原因所在。下面的程序演示了枚举的用法classProgramenumColor/定义枚举Red,Green,BluestaticvoidMain(stringargs)Colormyc=Color.Green;/给枚举变量赋值switch(myc)/判断枚举变量是什么值caseColo

24、r.Red:Console.WriteLine(redvalue=0,(int)myc);break;caseColor.Green:Console.WriteLine(greenvalue=0,(int)myc);break;caseColor.Blue:Console.WriteLine(bluevalue=0,(int)myc);break;2)结构)结构像类一样,结构可以包含数据成员和函数成员;与类不同的是:结构是值类型(不用分配堆),结构类型的变量直接保存结构的数据,而不是对象的引用。结构的一般定义为:修饰符struct结构名/下面是结构体,用于定义结构的成员修饰符类型字段;/数据成

25、员修饰符类型方法()/方法结构存在的原因一般情况下,用类即可满足要求;但如果要求程序的性能高(运行快,节省空间),对于小的数据结构,用结构可以节省存储空间。这正是结构存在的原因所在。下面定义了点结构:structPointpublicintx,y;publicPoint(intx,inty)this.x=x;this.y=y;使用结构的代码片段如下:Pointp1=newPoint(10,10);/给结构变量赋值Pointp2=p1;/赋值使p2建立了一个p1的副本p1.x=100;/修改p1.x,但p2.x不会受影响如果用类定义Point,则p2=p1语句使p1和p2变量引用同一个对象,当修

26、改p1的值(p1.x=100),p2.x也发生了变化。这正是值类型与引用类型的差别。可空类型和不可空类型可空类型和不可空类型(分类方法(分类方法3)如果按类型是否接受null值来区分,C#类型可分为可空类型(可空类型(Nullable)和不可空类型。)和不可空类型。引用类型是可空类型,而其它的是不可空类型。但C#提供了一种“可空类型”语法,只要在任何不可空类型后加“?”,就构成了可空的类型,如“int?”、“bool?”,所以下面语句是正确的:int?i=null;/null不等价于0stringst=null;/null不等价于无字符的串泛型和非泛型(分类方法泛型和非泛型(分类方法4)泛型泛

27、型 见第见第12章章如果按类型是否接受参数来区分,C#类型可分为泛型(generic)和非泛型。泛型引入了类型参数,由一个泛型可以派生出许多特定的类型。“可空类型”语法其实就是泛型System.Nullable的简写,其中T是参数。int?是System.Nullable的简写。下面的二条语句是等价的:int?i=null;System.Nullablej=null;2.3.2 简单类型简单类型(系统定义的值类型)(系统定义的值类型)简单类型包括数值类型以及bool和char类型。内容见教材,请自学2.3.4 结构类型(自定义的值类型)结构类型(自定义的值类型)内容见教材,请自学2.3.5 字

28、符串字符串(系统定义的引用类型)(系统定义的引用类型)【例2-10】字符串操作:“加”法,取子字符串,替换,插入等。staticvoidMain()strings1=小鸟;/定义一个字符串变量s1,并赋值strings2=s1+飞翔;/字符串“加”法/结果:s2=小鸟飞翔strings3=s2.Substring(1,3);/从字符串的开始位置1,取得长度为3的子串/结果:s3=鸟飞翔s3=s2.Replace(飞翔,自由);/把s2中子串飞翔替换为自由/结果:s3=小鸟自由s3=s3.Insert(2,-);/从位置2,插入字符串-/结果:s3=小鸟-自由boolisEqual=(s1=s2

29、);/判断二个字符串是否相等/结果:isEqual=falseboolisContain=s2.Contains(鸟飞翔);/判断s2中是否包含某字符串/结果:isContain=true/静态方法Format,格式化一个字符串,它与控制台程序格式化是相同的。s1=string.Format(小鸟飞了0公里,9);/结果:s1=小鸟飞了9公里部分string方法和属性2.3.6 数组(自定义的引用类型)数组(自定义的引用类型)数组是一种具有相同类型和名称的变量的集合,如一组整数、一组字符等。1) 一维数组一维数组一维数组类型的语法是在“非数组类型”后放方括号,一般形式为:非数组类型inta;/

30、声明了一个数组变量a,初值null,a还没有分配内存空间。a=newint2;/在堆上分配了有2个整数单元的内存,其地址赋给了变量aa0=6;a1=4;/对数组的元素进行赋值。2) 多维数组(矩形数组)多维数组(矩形数组)一般形式为:非数组类型n个逗号n个逗号表示的是数组的维度,即n+1维的数组。例如,int,表示二维整数数组类型,而下面的语句声明了一个二维数组b:int,b=newint3,21,2,3,4,5,6;或:int,b=newint3,21,2,3,4,5,6;2.3.7 object类型类型(系统定义的引用类型)(系统定义的引用类型)所有的结构类型隐式地继承object类型,这

31、样任何类型的值都能够被处理成对象。值类型的值可以通过执行装箱(boxing)的操作处理为对象,也可用取消装箱unboxing,把object对象还原成值类型的值。inti=123;objectobj=(object)i;/装箱intj=(int)obj;/取消装箱2.3.8 变量类型之间的转换变量类型之间的转换有四种转换方式:隐式转换、强制类型转换、ToString函数、Convert类。1)隐式转换)隐式转换若两种变量的类型是兼容的或者目标类型的取值范围大于源类型时就可以使用隐式转换。inti=12;doublef=i;/隐式转换成功i=f;/不成功,因为f取值范围大于i2) 强制类型转换强

32、制类型转换强制类型转换告诉编译器:将一种类型的变量转换为另外一种类型的变量。隐式转换不能满足所有的编程需要,很多时候还是需要强制类型转换的。但强制转换可能产生的结果不够精确。强制类型转换语法为:(target-type)变量或表达式;inti=2;doubled=3.4;intv1=(int)(i+d);/强制转换:double-int数值3) ToString函数函数ToString函数用于将变量转化为字符串,各种类型的变量都可以用ToString。下面的代码把int变量转为字符串:inti=250;/i是整型变量strings=i.ToString();/结果:变量s的值是字符串“250”

33、4) Convert类类ToString无法把一个字符串转为double类型的值。但可使用Convert类进行显示转换。例如:doubler=Convert.ToDouble(“3.14”);/Convert是静态类,ToDouble是它的函数运行结果:r=3.14,其值是由字符串“3.14”显示转换来的。表2-9Convert类的常见函数(见教材)2.4 运算符运算符运算符是用来定义表达式操作符的。C#提供了大量的运算符,从功能上可分为:算术运算符(+,-,*,/,%)位运算符(,&,|,)逻辑运算符(&,|,!)条件(赋值)运算符(? : )赋值运算符(=,+=,-=,*=,/=,%=,位

34、运算符=)关系运算符(=,!=,=)从运算对象上可以分为:单目运算符、双目运算符和三目运算符。2.4.1 算术运算符和自增自减运算符算术运算符和自增自减运算符算术运算符是指对数值(如整数、小数等)进行算术运算所用的运算符,包括:加(+)、减(-)、乘(*)、除(/)、取余(%)自增和自减运算符包括:+,-自增运算符其实是加1的简化表示法,自减运算符是减1的简化表示法。例如x=x+1,用自增表达式表示为:x+,或:+x2.4.2 位运算符位运算符位运算符有六种:,&,|,5&y=5);/y=5为true,但x5为false,故a=false结果:a=false其它逻辑运算见教材。2.4.4 关系

35、运算符关系运算符关系运算符又称为比较运算符,包括:=,!=,=它们一般用于条件表达式中,用来判断表达式是否符合条件。以上运算符的含义见教材的表2-13。假设x和y是double变量,如x=-6.4,y=3,则下面都是合法的关系表达式:xyx+3=y(x3)!=(y=5)三个关系表达式的结果分别为:false,false,true2.4.5 条件运算符条件运算符条件运算符是C#中唯一的一个三元运算符。一般形式为:?:如果满足条件就执行表达式1,否则执行表达式2。条件运算符常常用于条件赋值,一般形式为:变量=?:intb,x=6,y=4;b=(y一元算术移位关系按位逻辑赋值表示优先级高于。运算符中

36、的一元运算符(!等)是例外,其他都遵循这个规律。2.5.2 运算符的结合性运算符的结合性结合性表示:当优先级相同的时候,按照运算符的结合方向确定运算的次序。运算符的结合性分为两种方式:左结合(从左到右)右结合(从右向左)左结合-从左到右,是一般方式。例如算术运算符:+,-,*,/结合性结合性只有三个运算符是从右至左结合的,它们是:一元运算符、条件运算符、赋值运算符。其它的都是从左至右结合。从左至右结合:x=10/2*5;/等价于x=(10/2)*5;赋值运算符从右至左结合:x=y=3;/等价于y=3;x=y;点运算是自左向右结合的,因此a.b.c的含义是(a.b).c而不是a.(b.c)。System.Console.Write(OK);/等价于:(System.Console).Write(OK);2.6 编程练习编程练习1 编程要求编程要求编写一个控制台程序,程序可以从键盘读一组正整数,读到-1结束;程序对输入的一组正整数进行计数,并记录最大和最小数,最后输出它们。2 编程要点编程要点编程要用循环语句(while)等待用户从键盘输入,用条件语句(if)判断不同情况,做不同的处理,然后用控制台的WriteLine函数输出结果。感谢!

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号