1、第2章,C#编程语言基础,2,第2章 C#编程语言基础,2.1 C#程序构成 2.2 C#数据类型 2.3 常量、变量与表达式 2.4 基本结构,3,学习目标,掌握C#的基本数据类型 掌握C#各种运算符表达式的用法; 理解C#控制台程序的基本结构; 会使用IF、WHILE、FOR等语句编写程序.,4,2.1 C#程序构成,有若干种不同类型的声明空间: 在程序的所有源文件中,一个声明语句(称为“命名空间成员声明”)若没有被置于任何一个“命名空间声明”下,它就属于一个组合声明空间(称为“全局声明空间”)。 在程序的所有源文件中,一个“命名空间成员声明”若在“命名空间声明”中具有相同的完全限定的命名
2、空间名称,它就属于一个组合声明空间。 每个类、结构或接口声明创建一个新的声明空间。新的声明空间名称是通过“类成员声明”、“结构成员声明”或“接口成员声明”引入的。除了重载实例构造函数声明和静态构造函数声明外,类或结构成员声明不能引入与该类或结构同名的成员。类、结构或接口允许声明重载方法和索引器。另外,类或结构允许重载实例构造函数和运算符的声明。例如,类、结构或接口可以包含多个同名的方法声明,前提是这些方法声明的签名不同。注意,基类与类的声明空间无关,基接口与接口的声明空间无关。因此,允许在派生类或接口内声明与所继承的成员同名的成员。我们说这类成员“隐藏”了那些被它们所继承的成员。,5,2.1
3、C#程序构成,每个枚举声明创建一个新的声明空间。名称通过“枚举成员声明”引入此声明空间。 每个“块”或“switch 块”为局部变量和常量创建一个不同的声明空间。名称通过“局部变量声明”和“局部常量声明”引入此声明空间。如果块是实例构造函数、方法或运算符声明的体,或是索引器声明的 get 或 set 访问器,这些声明中声明的参数是块的局部变量声明空间的成员。块的局部变量声明空间包含任何嵌套块。因此,在嵌套块中不可能声明与封闭它的块中的局部变量同名的局部变量。 每个“块”或“switch 块”都为标签创建一个单独的声明空间。名称通过标记语句引入此声明空间,通过 goto 语句被引用。块的“标签声
4、明空间”包含任何嵌套块。因此,在嵌套块中不可能声明与封闭它的块中的标签同名的标签。 声明名称的文本顺序通常不重要。具体说来,6,2.1 C#程序构成,字段声明和局部变量声明的声明顺序确定其初始值设定项(若有的话)的执行顺序。 在使用局部变量前必须先定义它们。 当省略“常数表达式”值时,枚举成员声明的声明顺序非常重要。,7,C#应用程序的结构,1 命名空间 C#程序是用命名空间来组织代码,要访问某个命名空间中的类或对象,必须用如下语法: 命名空间.类名 由于Console类位于System命名空间中,所以实际上用户在访问Console类时,完整的写法应该是: System.Console 类 C
5、#程序由大括号“”和“”构成,程序中每一对大括号“ ”构成一个块。大括号成对出现,可以嵌套,即块内可以出现子块,嵌套深度不受限制,可以嵌套任意层,但一定要保证“”和“”成对出现,否则,程序就是错误的。 注意: C#程序中的语句以“;”表示结束,8,3Main( )方法 程序的入口从下面的代码开始: static void Main( ) 4注释 在C#语言中,提供了两种注释方法: (1) 每一行中“/”后面的内容作为注释内容,该方式只对本行生效; (2) 需要多行注释的时候,在第一行之前使用“/*”,在末尾一行之后使用“*/”,也就是说被“/*”与*/所包含的内容都作为注释内容。,9,2.2
6、C#数据类型,C#语言的类型如图,10,2.2.1 值类型,1简单类型(Simple Type),11,2枚举类型(Enum Type),访问修辞符 enum 枚举名:基础类型枚举成员,12,3结构类型,结构类型也是先声明后使用。声明结构类型时要使用struct关键字,声明结构类型的一般语法格式如下: struct 标识符 结构成员定义; 说明: (1)struct关键字表示声明的是一种结构类型。 (2)标识符必须是C#合法的标识符,它用来在程序中唯一确定所定义的结构。 (3)由一对花括号括起来的部分称为结构体,它定义了结构中所包含的各种成员。,13,3结构类型,struct Student
7、/定义名为Student的结构类型 long no; /定义结构的数据成员string name;int age;string university;/定义结构的方法成员void structmethod( )/方法可执行代码 ,14,2.2.2 引用类型,引用类型是将数据保存在堆上的存储方式。当将一个数据给引用类型时,它被保存在堆上的变量中。引用类型的大小不固定,为了可以快速地搜索引用类型数据的值,通过将其地址保存在堆栈上,可以通过地址找到真正数据的所在。引用类型很抽象,就像一个门牌号,可以根据门牌号找到所在的房子。,15,2.2.2 引用类型,C#引用类型和值类型的主要区别有: 值类型变量
8、直接包含它们的数据,对于值类型,每个变量都有它们自己对数据的拷贝,所以不可能因为对一个进行操作而影响到其它变量;然而引用类型是存储对象的引用。 如果两个变量引用相同的对象,对一个变量的操作会影响到另一个变量所引用的对象。从存储方式来看,值类型的变量本身包含它们的数据值,将存储在栈中。而引用类型的变量包含的是指向含数据值的内存块的位置信息,将存储在受控的堆中。 C#的类型系统是统一的,因此任何类型的值都可以按对象处理。C# 中的每个类型直接或间接地从 object 类类型派生,而 object 是所有类型的最终基类。引用类型的值都被当作“对象”来处理,这是因为这些值可以简单地被视为是属于 obj
9、ect 类型。值类型的值则通过执行装箱 (boxing) 和拆箱 (unboxing) 操作亦按对象处理。,16,2.3 常量、变量与表达式,2.3.1 常量 1直接常量 直接常量即数据值本身。 (1)整型常量 C#语言整型常量的三种表示形式: 十进制整数,如12, -314, 0。 八进制整数,要求以0开头,如012 十六进制数,要求0x或0X开头,如0x12 C#语言的整型常量默认为int型,如: int i =3; 声明long型常量可以后加l或L ,如: long l = 3L;,17,2.3 常量、变量与表达式,(2)实型常量 C#浮点类型常量有两种表示形式: 十进制数形式:必须含有
10、小数点,例如: 3.14 314.0 .314 科学记数法形式:如: 3.14e2 3.14E2 314E2 C#浮点型常量默认为double型,如要声明一个常量为float型,则需在数字后面加f或F,如: double d = 3.14; float f = 3.14f; (3)字符常量 字符常量是用单引号括起来的单个字符,如: char c = A;,18,转义字符,19,(4)字符串常量 字符串常量是用双引号括起的零个或多个字符序列。C#支持两种形式的字符串常量,一种是常规字符串,另一种是逐字字符串。常规字符串就是用双引号括起的一串字符,可以包括转义字符。如:”China,Beijing
11、”, “d:myfilef1.txt”等。 (5)布尔常量 boolean类型适于逻辑运算,一般用于程序流程控制。 boolean类型数据只允许取值true或false,不可以0或非0的整数替代true和false。,20,2. 符号常量,符号常量通常用来保存一个固定值,例如,在程序设计中,圆周率“PI”是一个固定的值,那么,在程序开始时,就可以将其定义为一个常量。 常量的定义语法如下所示,其中,“const”是定义常量的关键字,同时还要将变量名大写。 const 类型名称 常量名 = 常量表达式;,21,2.3.2变量,1变量命名规则 变量名的第首字符必须是字母、汉字或下划线。 变量名中不能
12、包含空格、小数点以及各种符号。 组成变量名的字符数不要太长,应控制在330个字符。 变量名不能是关键字。如:int,object等不能用作变量名。 变量名在同一范围内必须是唯一的。 在C#中声明变量使用下述语法: 类型 标识符; 例如:int i;,22,2变量的初始化,C#有两个方法可确保变量在使用前进行了初始化: (1)变量是类或结构中的字段,如果没有显式初始化,在默认状态下创建这些变量时,其值就是0。 (2)方法的局部变量必须在代码中显式初始化,之后才能在语句中使用它们的值。此时,初始化不是在声明该变量时进行的,但编译器会通过方法检查所有可能的路径,如果检测到局部变量在初始化之前就使用了
13、它的值,就会产生错误。,23,3变量的作用域,变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域有以下规则: 只要字段所属的类在某个作用域内,其字段(也称为成员变量)也在该作用域内(在C+、Java和 VB中也是这样)。 局部变量存在于表示声明该变量的块语句或方法结束的封闭花括号之前的作用域内。 在for、while或类似语句中声明的局部变量存在于该循环体内(C+程序员注意,这与C+的ANSI标准相同。Microsoft C+编译器的早期版本不遵守该标准,但在循环停止后这种变量仍存在)。,24,3变量的作用域,(1)局部变量的作用域冲突 大型程序在不同部分为不同的变量使用相同的变量
14、名是很常见的。只要变量的作用域是程序的不同部分,就不会有问题,也不会产生模糊性。但要注意,同名的局部变量不能在同一作用域内声明两次,所以不能使用下面的代码: int x = 20; int x = 30;,25,3变量的作用域,(2)字段和局部变量的作用域冲突 在某些情况下,可以区分名称相同(尽管其完全限定的名称不同)、作用域相同的两个标识符。此时编译器允许声明第二个变量。原因是C#在变量之间有一个基本的区分,它把声明为类型级的变量看作是字段,而把在方法中声明的变量看作局部变量。,26,2.3.3 运算符与表达式,算术运算符 算术运算符是常见的数学运算,算术运算符有一元运算符与二元运算符。 一
15、元运算符:-(取负)、+(取正)、+(增量)、-(减量)。 二元运算符:+(加)、-(减)、*(乘)、/(除)、%(求余)。下面的代码演示了常见的4种算术运算,注意,这些参与运算的变量的数据类型,一定是可计算的类型。,27,2.3.3 运算符与表达式,2字符串运算符 字符串运算符是常用的运算符号,用在字符串和字符的处理上。在C#中,字符串运算最常用的运算符是“+”和“ ”。“+”用来连接两个字符串,虽然效率有些低,但使用方便。“ ”用来以索引方式查找字符串数组中的值,可以被称为字符串的索引器。,28,2.3.3 运算符与表达式,3赋值运算符 赋值运算符就是常见的“=”,它可以为数值型、枚举、类
16、等所有的类型赋值。使用“=”的语法如下所示: 变量 = 值; 其中,“=”左边一般为变量的名称,“=”右边为固定的值、已经知道的变量或新实例化的类。还有一种赋值运算符可计算后再赋值。如“+=”或“-=”。,29,2.3.3 运算符与表达式,4关系运算符与关系表达式 (1)关系运算符,30,2.3.3 运算符与表达式,(2)关系表达式 关系表达式由操作数和关系运算符组成。关系表达式中既可以包含数值,也可以用于字符或字符串,但是用于字符串的关系运算符只有相等“=”和不等“!=”两种运算符。,31,2.3.3 运算符与表达式,5逻辑运算符 逻辑运算就是常说的“是否”操作,“是”就执行A代码,“否”就
17、执行B代码。逻辑运算符一般包括“与”、“或”、“非”。 与:C#中的符号为“&”,表示必须满足两个条件。语法为“表达式1 & 表达式2”。 或:C#中的符号为“|”,表示满足两个条件中的任意一个即可。语法为“表达式1 | 表达式2”。 非:C#中的符号为“!”。表示取当前表达式结果的相反结果。如果当前表达式为“true”,则计算结果为“false”。语法为“! 表达式”。,32,2.3.3 运算符与表达式,6位运算符,33,2.3.3 运算符与表达式,7条件赋值运算符及表达式 条件赋值表达式可以看作是逻辑表达式和赋值表达式的组合,它可根据逻辑表达式的值(true或false)返回不同的结果。条
18、件运算符由符号“?”与“:”组成,通过操作三个操作数完成运算,其一般格式为: 逻辑表达式 ? 表达式1:表达式2 在条件赋值表达式在运算时,首先运算“逻辑表达式”的值,如果为true,则运算结果为“表达式1”的值,否则运算结果为“表达式2”的值。 如:条件表达式43?1:2的值为1;条件表达式34?1:2的值为2。,34,2.4 基本结构,2.4.1顺序结构 1. 赋值语句 赋值语句是最简单的语句,其一般形式为:= 赋值语句的作用是计算表达式的值,并赋给变量。对于任何一个变量必须首先赋值,然后才能引用,否则,未赋初值的变量将不能参与运算。另外,赋值号两边的类型必须相同,或者符合隐式类型转换规则
19、。 例如: int age = 30;,35,2. 输入语句,C#语言的输入语句有如下两种形式: Console.Read(); Console.ReadKey(); Console.ReadLine(); 输入可以是整型或字符串等,但布尔型不可以直接读入。 例如:strInput为字符串变量,ReadLine之后,将赋予变量对应的值。 string strInput = Console.ReadLine(); 键盘输入:20 回车 结果:strInput = 20; Read语句和ReadLine语句不同之处在于输入数据到各变量之后,ReadLine自动换行,从下一行开始再输入数据。一个Re
20、ad语句执行完后,数据行中多余的未读数据可以被下一个输入语句读入;而一个ReadLine于执行完后,数据行中多余未读数据就没有用了。,36,3. 输出语句,C#语言的输出语句有两种形式: Console.Write(输出项); Console.WriteLine(输出项); 其中可以是常量、变量、表达式或字符串。如果是变量、表达式,则将其计算结果输出;如果是常量或字符串,则直接输出其值。 Write和WriteLine的区别在于:Write语句是输出项输出后,不换行,光标停留在最后一项后,WriteLine语句按项输出后,自动换行,光标则停留在下一行的开始位置。 WriteLine语句允许不含
21、有输出项,即仅WriteLine;表示换行。,37,4. 复合语句,复合语句是由若干语句组成的序列,语句之间用分号“;”隔开,并且以 括起来,作为一条语句。复合语句的一般形式:语句1;语句2;语句n; 例如:变量值的交换int x = 10;int y = 100;int buffer = x;x = y;y = buffer;,38,2.4.2选择结构,1. 使用if语句实现单分支选择结构 if语句用于判断表达式的值,满足条件时执行其包含的一组语句。其语法如下:if(表达式)语句1;语句2;语句n; 如果表达式的值为true(真),则执行语句块一中的语句;如果表达式的值为false(假),则
22、不执行语句块一中的语句。,39,2. 使用ifelse语句实现双分支选择结构,ifelse语句根据表达式的值有选择地执行程序中的语句。 其声明语法如下:if(表达式)语句1;语句2;语句n;else语句1;语句2;语句n;如果表达式的值为true(真),则执行if语句块中的语句;如果表达式的值为false(假),则执行else语句块中的语句。,40,3. 使用ifelse ifelse语句实现多分支选择结构,有时必须判定多个条件以便决定执行什么操作。在这种情况下就要使用ifelse ifelse语句。其声明语法如下:if(表达式1)语句1;语句2;语句n;else if(表达式2)语句1;语句
23、2;语句n;else if(表达式3)else if(表达式4)else语句1;语句2;语句n;,41,3. 使用ifelse ifelse语句实现多分支选择结构,执行过程说明如下: (1)首先判断表达式1,如果其值为true,则执行if语句块中的语句,然后结束if语句。 (2)如果表达式1的值为false,则判断表达式2,如果其值为true,则执行else if语句块中的语句,然后结束if语句。 (3)如果表达式2的值为false,再继续往下判断其他表达式的值。 (4)如果所有表达式的值都为false,则执行else语句块中的语句,然后结束if语句。,42,4. 嵌套if语句的使用,其声明语
24、法如下:if(表达式1)语句1;语句2;语句n;if(表达式2)语句1;语句2;语句n; 对于多层if嵌套结构,要特别注意if与else的配对关系,一个else必须与一个if配合。一定要使用代码缩进,这样便于日后的阅读与维护。,43,5. 使用Switch语句实现多分支选择,在判定多个条件时,如果用ifelse ifelse语句可能会很复杂和冗长。在这种情况下,应用switch语句就会简明清晰得多。用switch语句可以将任何整型变量或字符串与多个值进行检查。当两者匹配时就会执行相应的所有语句。 其声明语法如下:Switch(表达式)Case 常数表达式:语句块跳转语句(如break、retu
25、rn、goto)/其他的case子句Defalut:语句块,44,2.4.3循环结构,1. for语句 当你预先知道一个内含语句应要执行多少次时,for 语句特别有用。当条件为真时,常规语法允许重复地执行内含语句。 其声明语法如下:for (初始化;条件;循环)内含语句 请注意,初始化、条件和循环都是可选的。比如你可以在其他地方初始化,在for循环就不用再次进行初始化了。,45,2. foreach语句,foreach语句用来循环一个集合中的元素。由于C#中的数组支持foreach语句,因此你可以应用foreach语句处理数组中的每一个元素。 使用foreach语句时,首先输入foreach关
26、键字,然后是括号。括号内必须包含以下信息:集合中元素的类型、集合中元素的标识符名称、关键字in和集合的标识符,嵌套语句在括号之后。 其声明语法如下:foreach( 元素类型 元素变量 in 元素变量集合)循环语句,46,3. while语句,while语句表示条件满足时执行循环体,循环体的执行次数我们是可以控制的,可以0次,可以1次,也可以无数。 其声明语法如下:while(条件表达式)循环语句 当条件表达式的值为真时,这个语句执行循环语句。控制while语句的布尔表达式包含在括号内,前面是while关键字。括号后面是当布尔表达式值为真时应执行的语句。,47,4. do-while语句,do
27、-while语句与while语句十分相似,do-while语句执行其嵌套语句0次或多次。如果while语句中的布尔表达式值为假,则不执行任何嵌套语句。但是,为了保证嵌套语句至少执行一次,就可以使用do-while语句。 其声明语法如下:do循环语句 while(条件表达式) do语句后面是一个循环语句,后面紧跟着一个while关键字。控制循环执行次数的布尔表达式位于while关键字的后面。由于布尔表达式在嵌套语句执行后再求值,因此嵌套语句至少被执行一次。,48,2.4.4 continue、break与return语句,1. break语句 break语句会使运行的程序立刻退出它所在的最内层循
28、环或者退出一个switch语句。由于它是用来退出循环或者switch语句,所以在其他地方使用break语句是不合法的,只能在循环体内和switch语句体内使用break语句。规则如下: 1) 当break语句出现在循环体中的switch语句体内时,其作用只是跳出该switch语句体。 2) 当break语句出现在循环体中,但并不在switch语句体内时,则在执行break后,跳出本层循环体。 如果一个循环的终止条件非常复杂,那么使用break语句来实现某些条件比用一个循环表达式来表达所有的条件容易得多。,49,2. continue语句,continue语句和break语句用法相似。不同的是,
29、它不是退出一个循环,而是不执行本次循环剩下的代码,开始执行下一次循环。 continue语句只能用在while语句、do-while语句、for语句、或者foreach语句的循环体内,在其它地方使用都会引起错误。,50,3. return语句,return语句就是用于指定函数返回的值。return语句只能出现在函数体内,出现在代码中的其他任何地方都会造成语法错误。规则如下: 1) 使用return语句从当前的方法中退出,返回到该调用的方法的语句处,继续执行。 2) 使用return语句返回一个值给调用该方法的语句,返回值的数据类型必须与方法的声明中的返回值的类型一致,可以使用强制类型转换来保持数据类型一致。 3) 当方法说明中用void声明返回类型为空时,应使用return语句,但不返回任何值。,