网页嵌套另一网页怎么实现?求助,想在网页内实现嵌入另一网页的局部线性嵌入算法,并且手机电脑都能正常显示。

如何嵌套别人的网页的局部_百度知道
如何嵌套别人的网页的局部
静态页面的话,在网页上右击 源代码,把代码粘过来就行了,改改样式和图片
其他类似问题
为您推荐:
其他1条回答
用静态的可以用iframe就可以
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁网页试题_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩6页未读,继续阅读
你可能喜欢新建网页 1
C#编程语言基础
在认识了C#之后,就可以如何使用它。本章将介绍C#编程的基础知识,这也是后续章节的基础。其中包括变量与表达式、流程控制、复杂的数据类型和函数。阅读完本章之后,读者就有足够的C#知识编写简单的程序了,但还不能使用面向对象的特征。
变量与表达式
变量表示内存中具有特定属性的一个存储位置,它用来存储数据。每个变量都属于某一种类型,用以确定什么样的值可以存储在该变量中。
2.1.1.1变量声明
要使用变量,需要先声明,即给变量一个名称和一种类型,在C#中声明变量的语法如下:
&&&&& &datatype& &name&;
&&& 例如:
该语句声明一个int类型的变量i。
可以在一个语句中声明多个类型相同的变量,方法是:在类型的后面用逗号分隔变量名,如下所示:
& int x,y;
其中x和y都声明为整数类型。
变量的类型有多种,这部分内容详见2.1.2节。
中用来对变量、函数、数组、类型(如类)等数据对象命名的有效字符序列统称为标识符。标识符不能为任意序列,C#语言规定标识符的第一个字符必须是字母、下划线“_”或“@”,其后的字符可以是字母、下划线或数字。另外,关键字对C#编译器来说有特定的含义,例如using和class,因此,变量名也不能和关键字重复。(C#中的关键字表见附录I)
下面列出的标识符是合法的,可以作为变量名:
& _Identifier
下面是不正确的标识符和变量名:
99BottlesOfBeer
注意,C#区分大小写,因此,sum和Sum是两个不同的变量名。
在选择变量名和其他标识符时,应注意做到“见名知意”,即根据变量的作用来命名它。在.NET
FrameWork命名空间中有两种命名约定,称为PascalCase和camelCase。在由多个单词组成的名称中,PascalCase指定名称中的每个单词除了第一个字母大小外,其余字母小写;在camelCase中,第一个单词以小写开头,其他同PascalCase。
下面是camelCase变量名:
& firstName
下面是PascalCase变量名:
& LastName
Microsoft建议:对于简单的变量,使用camelCase规则,而对于比较高级的命名则使用PascalCase。
2.1.1.2变量的初始化
变量在使用前,必须初始化。
我们可以先声明一个变量,然后用“=”赋值运算符给变量赋值。例如:
& age = 25;
也可以在声明变量的同时赋值,即:
& int age = 25;
如果有多个变量,可使用以下技巧:
& int x = 3, y = 4;
注意下面的代码:
& int x, y = 4;
其结果是y被初始化了,而x仅进行了声明。
2.1.1.3常量
常量是其值在使用过程中不会发生变化的变量。在声明和初始化变量时,加上关键字const,就把该变量指定为一个常量:
const int a = 100;
使用常量的好处如下:
(1)含义清楚。在一个规范的程序中不提倡使用很多的常数,如:sum
= 15 * 30 * 23.5,搞不清各个常数究竟代表什么,给阅读程序带来困难。
(2)使程序更易于修改。例如在C#程序中有一个代表某物品的价格的常量Price,在价格调整时,可以把新值赋给这个常量,就可以修改所有出现的价格。如果使用常数的话,就需要查找整个程序,作多处修改。
前面介绍了如何声明变量和常量,下面将详细讨论C#中可用的数据类型。
C#把数据类型分为两种:值类型和引用类型,其区别如下:
(1)值类型在堆栈中直接存储其值,等价于其他语言的简单类型(整型、浮点型)。
(2)引用类型在堆中存储值的引用,与C++中指针相似。
2.1.2.1值类型
C#提供了一套预定义类型,内置的值类型识别基本数据类型,例如整数、浮点数、字符和布尔类型。
C#支持8个预定义整数类型,如表2.1所示
预定义整数类型
8位有符号的整数
-128~127(-27~27-1)
8位无符号的整数
0~255(0~28-1)
16位有符号的整数
-(-215~215-1)
16位无符号的整数
0~65535(0~216-1)
32位有符号的整数
-~(-263~263-1)
32位无符号的整数
0~(0~232-1)
64位有符号的整数
-5807(-263~263-1)
64位无符号的整数
0~(0~264-1)
注意:C#中,byte类型和char类型完全不同,它们之间的赋值必须进行强制类型转换。另外,与其他整数类型不同,byte类型在默认状态下是无符号的。
一个整数可以通过添加0x前缀,来表示一个16进制的数,例如:0x12ab。
对于一个整数,还可以添加一些后缀,指定其类型,如下表2.2所示。
int,uint,long,ulong
uint,ulong
long,ulong
ul,uL,Ul,UL,lu,lU,Lu或LU
C#支持的浮点数类型有3种:float,double和decimal。前两种用+/-m×2e的形式存储浮点数,decimal类型使用+/-m×10e的形式,如表2.3所示。
浮点数类型
近似的范围
32位单精度浮点数
±1.5×10-45~±3.4×1038
64位双精度浮点数
±5.0×10-324~±1.7×10308
128位高精度十进制表示法
±1.0×10-28~±7.9×1028
在C#中,一个非整数数字默认为double类型,也可以用后缀d或D来说明是double类型。如果想指定为flaot类型,可以在其后加上后缀f或F;想指定为decimal类型,可以添加后缀m或M,例如:
1.5&&&& //double类型
1.5F&&& //float类型
1.5M&& //decimal类型
&&& 3.字符类型
&&& C#支持char类型,以保存单个字符的值。char类型使用16位,表示一个Unicode字符。
&&& char类型的字面值使用单引号括起来,例如’a’。如果使用双引号,则会被认为是一个字符串。’a’和”a”是不一样的。C#还包含一个转义序列,如表2.4所示。
字符的Unicode值
响铃(警报)
水平制表符
垂直制表符
4位16进制的Unicode值对应的字符
16进制数对应的Unicode字符
4.布尔类型
C#的bool类型用于包含布尔值true或false。bool值和整数值之间不能相互转换。如果变量声明为bool类型,就只能使用值true或false。不能使用0表示false,非0表示true。
引用类型包括类类型、接口类型、数组类型、委托类型等。C#支持两个预定义的引用类型,object类型和string类型。
1.object类型
在C#中,object类型是所有其他类型的最终父类型,也就是说C#中所有类型都是直接或间接地从object类型派生出来的。
第3章中将详细介绍object类型。
2.string类型
在C或C++中,字符串实际上就是一个字符数组,那么把一个字符串复制到另一个字符串,或者连接两个字符串,都需要大量工作。而C#提供了自己的字符串类型:string类型。像上面的操作就变得很简单了:
& string str1 = “Hello ”;
& string str2 = “World”;
& string str3 = str1 + str2; //连接2个字符串
因为string类型是一个引用类型,所以当把一个字符串赋给另一个字符串时,就会得到对同一内存空间内字符串的两个引用。修改一个字符串,实际上会创建一个全新的string对象。参看下面的代码:
class StringExample
&&& static void Main(sting[] args)
&&&&&&&&&& string s1 = &a string&;
&&&&&&&&&& string s2 = s1;
&&&&&&&&&& Console.WriteLine(&s1 is & + s1);
&&&&&&&&&& Console.WriteLine(&s2 is & + s2);
&&&&&&&&&& s1 = &another string&;
&&&&&&&&&& Console.WriteLine(&s1 is now & + s1);
&&&&&&&&&& Console.WriteLine(&s2 is now & + s2);
&&& 其输出结果为:
&&&&& s1 is a string
&&&&& s2 is a string
&&&&& s1 is now another string
&&&&& s2 is a string
&&& 这个结果与我们对引用类型的理解刚好相反――改变s1的值并未对s2产生影响。首先声明字符串对象s1,并用’’a
string”初始化之。接着声明字符串对象s2,引用和s1相同,所以s2的值也是”a
string”。然后改变s1的值,使其为”another
string”,但此时不是替换原来的值,而是为新值分配一个新对象。由于s2仍然指向原来的对象,所以它的值没发生变化。
&&& C#中的字符串和char类型一样,可以使用转义序列。由于这些转义序列都以一个反斜杠开头,所以在字符串中要表示反斜杆,就需要用2个反斜杠(”\\”)。而在文件名中大量使用了反斜杠字符,这样的处理方式不免有些繁琐,例如:
&&&&& “C:\\Temp\\MyDir\\MyFile.doc”
&&& C#提供了一种可读性较高的替代方案:在字符串前面加上字符@,在这个字符后的所有字符都被看作原来的含义,即不会解释为转移字符。上面的例子等价于:
&&&&& @”C:\Temp\MyDir\MyFile.doc”
&&& 这种字符串还允许包含换行符:
&&&&& @”A short list
item2”&&&
&&& C#包含了多种运算符,把变量和字面值(操作数)和运算符结合起来,就是一个表达式。简单的表达式包括所有基本的数学运算,例如+运算符是把两个操作数相加;还有专门用于处理布尔值的逻辑运算符以及赋值运算符=等。
&&& 运算符大致分为3类:一元运算符(处理一个操作数)、二元运算符(处理两个操作数)、三元运算符(处理三个操作数)。大多数运算符都是二元运算符,只有几个一元运算符和一个三元运算符。详细说明,请参考附录B
&&& 1.数学运算符
&&& (1)+&
(加法运算符,正值运算符,或字符串连接,如3+5、+3、”Hello”+”World”)
&&& (2)-&&
(减法运算符,或负值运算符,如5-2、-3)
&&& (3)*&&
(乘法运算符,如3*5)
&&& (4)/&&
(除法运算符,如5/3)
&&& (5)%&
(求余运算符,如7%4)
&&& (6)++
(自增运算符,如++i,i++)
&&& (7)--&
(自减运算符,如―i,i--)
这些运算符都使用简单的数值类型(整数和浮点数),其中+可以用于字符串类型。需注意的是%运算符也可以用于浮点数。++(--)的作用是使变量的值增1(减1),而运算符的位置决定了它在何时发挥作用。把运算符放在操作数的前面,则操作数先增1(或减1),再参与其他运算;而把运算符放在操作数的后面,则操作数先参与其他运算,再自身增1(或减1)。如果i的原值等于3,则分析下面的赋值语句:
①j = i++;   (i的值先变成4,再赋给j,j的值为4)
②j = ++i;&&&&& (先将i的值3赋给j,j的值为3,然后i变成4)
自增(减)运算符使用起来非常方便,常用于循环语句中,这将在2.2节中介绍。
下面介绍一个例子,说明如何使用数学运算符。
&&&&& using S
&&&&& class MathClass1
&&&&&& & {&&&&&&&&
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& &&&&&& double Num1,Num2;
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Please input two
numbers:&);
&&&&&&&&&&&&&&&&&&&&
Num1=Convert.ToDouble(Console.ReadLine());
&&&&&&&&&&&&&&&&&&&&
Num2=Convert.ToDouble(Console.ReadLine());
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&{0} + {1} =
{2}&,Num1,Num2, Num1+Num2);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&{0} - {1} = {2}&,
Num1, Num2, Num1-Num2);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&{0} * {1} = {2}&,
Num1, Num2, Num1*Num2);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&{0} / {1} = {2}&,
Num1, Num2, Num1/Num2);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&{0} % {1} = {2}&,
Num1, Num2, Num%Num2);
&&&&&&&&&&&&& }
&&&&&& & }
&&& 假定输入两个数为32.76和19.43,输出为:
&&&&& 32.76 + 19.43 = 52.19.
&&&&& 32.76 - 19.43 = 13.33
&&&&& 32.76 * 19.23 = 635.5268
&&&&& 32.76 / 19.23 = 1.99
&&&&& 32.76 % 19.23 = 13.33
&&& 在这段代码中,使用了ReadLine()函数,作用是把用户输入的信息,存储到string变量中。由于我们需要得到一个数字,所以就引入了类型转换,这部分内容详见下节。得到2个double类型的数据后,输出它们的加、减、乘、除和取余的结果。
2.赋值运算符
&&& 赋值运算符“=”的作用是将一个数据赋给一个变量,如“a=3”的作用是把3赋给变量a。还可以在赋值符“=”之前加上其他运算符,构成复合的运算符。例如:
&&&&& a += 3&&&&& 等价于a
&&&&& x *= y + 8&& 等价于x
= x * (y +8)
&&&&& x %= 3&&&& 等价于x
&&& C#规定可以使用10种复合赋值运算符。即:
&&&&& +=,-=,*=,/=,%=,&=,|=,^=,&&=,&&=
&&& 后面5种是有关位运算的,稍后将介绍。
&&& 3.比较运算符
将两个值进行比较,判断其比较的结果是否符合给定的条件。例如,a&3是一个比较表达式,大于号(&)是一个比较运算符,如果a的值为5,则满足给定的“a&3”条件,因此比较表达式的值为&“真”;如果a的值为2,不满足“a&3”条件,则比较表达式的值为“假”。C#提供了6种比较运算符:
(1)&&&&&&&
(2)&=&&&&&
(小于等于)
(3)&&&&&&&
(4)&=&&&&&
(大于等于)
(5)==&&&&&
(6)!=&&&&&
(不等于)
比较表达式的值是bool类型的,可以有两个值:true或false。例如:
&&&&& bool d&;
&&&&& d = a & b&;
&&& 如果a存储的值比b存储的值大,就给b赋值true,否则就赋值false。
可以使用比较运算符的数据类型包括:数值类型、字符串类型和布尔类型等。但对布尔值只能使用==和&!=运算符。比如:
&&&&& bool isTrue&;
&&&&& isTrue = myBool == true&;
&&& 4. 逻辑运算符
&&& 在处理布尔值时,C#还提供了一些逻辑运算符。
&&& (1)!(逻辑非,如v1
= ! v2,若v2是false,v1的值就是true)
&&& (2)&(逻辑与,如v1
= v2 & v3,若v2和v3都是true,v1的值就是true,否则为false)
&&& (3)|
(逻辑或,如v1 = v2 |
v3,若v2和v3都是false,v1的值就是false,否则为true)
&&& (4)^(逻辑异或,如v1
= v2 ^ v3,若v2和v3逻辑值不同,v1的值就是true,否则为true)
&&& (5)&&(与&相同)
&&& (6)||(与|相同)
&&& 其中&&与||虽然和&与|结果相同,但得到结果的方式却不相同:其性能比较好。&&与||都是先检查第一个操作数的值,再根据该操作数进行操作,可能根本就不需要第二个操作数。如果&&运算符的第一个操作数的值是false,就不需要考虑第二个操作数了,因为无论第二个操作数的值是什么,其结果都是false。同样年,如果第一个操作数是true,||运算符就返回true,而无需考虑第二个操作数。例如:
&&&&& (m = a & b) && (n = c & d)
= 1,b = 2,c
= 3,d = 4,m和n的原值为true时,由于“a
& b”的值为false,因此m
= false,而“n = c &
d”不被执行,所以n的值不是false而仍保持原值true。
但&和|运算符的两个操作数总是要计算的。所以,如果使用&&和||运算符来代替&和|,性能会有一定的提高。
5.位运算符
&&& 在讨论逻辑运算符时,我们会质疑&和|的存在,既然有更高性能的运算符,为什么还要使用它们呢?原因在于它们处理的是变量中的一系列位,而不是变量的值,即它们是位运算符。这类运算符主要用于系统软件的编写,检测和控制领域。
&&& (1)&&
(按位与)
&&& (2)|&&&
(按位或)
&&& (3)^&&
(按位异或)
&&& (4)~&&
&&& (5)&&&
&&& (6)&&&
&&& 先讨论&,参加运算的两个数据,按照二进制位,把相同位置的位进行比较,按下表2.5得到结果。
表2.5 &运算
操作数1的位
操作数2的位
&&& |运算符与此类似,但得到的结果不同,如表2.6所示。
表2.6 |运算
操作数1的位
操作数2的位
&&& 例如,3&5,过程如下:
&&& 4|5,过程如下:
&&& ^运算符的用法与此相同。如果操作数中相同位置上的位有且仅有一个是1,其结果位就是1,如表2.7所示。
表2.7 ^运算
操作数1的位
操作数2的位
&&& ~运算符是一个一元运算符,用来对操作数种的位取反,即将0变1,将1变0,如表2.8所示。
表2.8 ~运算
操作数的位
&&& 最后,讨论位移运算符。&&用来将一个数的各二进制位全部左移若干位。例如:
&&&&& a = a && 2
&&& 将a的二进制数左移2位,右补0。若
a = 15,即二进制数,左移2位得,即十进制数60。实际上,我们执行了乘法操作。每向左移一位,该数都要乘以2,而每向右移动一位,则是给操作数除以2,并丢弃余数。例如:
&&&&& a = a && 1
&&& a的值是10,即,向右移2位得,即5。
下面的例子说明任何使用布尔和位运算符:
&&&&& using S
class Class1
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Enter an integer:&);
&&&&&&&&&&&&&&&&&&&& int
myInt=Convert.ToInt32(Console.ReadLine());
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Integer less than
10?{0}&,myInt&10);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Integer between 0 and
5?{0}&,(0&=myInt)&&(myInt&=5));
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Bitwise AND of
Integer and 10 = {0}&,myInt&10);&&&&&&&&&
&&&&&&&&&&&&& }
&&& 假设输入一个整数6,其输出结果为:
&&&&& Iteger less than 10? True
&&&&& Integer betweem 0 and 5? False
&&&&& Bitwise AND of Integer and 10 = 2
&&& 与上个例题相同,使用Convert.ToInt32()得到一个整数。第一个输出是操作myInt
& 10的结果。第二个输出是(0&=myInt)&&(myInt&=5)的结果,如果myInt是大于或等于0,且小于等于5,就输出true。最后一个操作是对myInt的值与10进行按位与操作的结果。
&&& 6.条件运算符
&&& 它是一个三元操作符,一般形式如下:
&&&&& &test& ? &resultTrue& : &resultFalse&
&&& 条件运算符的执行顺序:先求解&test&,若为true则求解&resultTrue&,此时表达式&resultTrue&的值就作为整个条件表达式的值。若&test&的值为false,则求解&resultFalse&,表达式&resultFalse&的值就是整个条件表达式的值。如:
&&&&& max = (a & b)? a : b
&&& 执行结果就是将a和b中大者赋给max。&&&
在表达式的计算中,我们常常需要把数据从一种类型转换为另一种类型,有两种类型转换的形式:
&&& (1)隐式类型转换:从类型A到类型B的转换可以在任何情况下进行,编译器自动进行。
&&& (2)显式类型转换:从类型A到类型B的转换只能在某些情况下进行,应进行某种处理才能进行。
&&& 1.隐式类型转换
隐式转换不需要我们做任何工作。看一个例子:
&&&&& byte v1 = 10;
&&&&& byte v2 = 23;
&&&&& sum = v1 + v2;
&&& 由于long类型变量包含的数据字节比byte类型多,所以没有数据丢失的危险,编译器就会顺利的进行转换,不需编写代码。
简单类型有许多隐式转换,但bool和string类型没有隐式转换。表2.9列出了C#支持的隐式类型转换。
隐式类型转换
可以安全地转换为
short、int、long、float、double、decimal
short、ushort、int、uint、long、ulong、float
double、decimal
int、long、float、double、decimal。
int、uint、long、ulong、float、double、decimal
long、float、double、decimal
long、ulong、float、double、decimal
float、double、decimal
float、double、decimal
ushort、int、uint、long、ulong、float、double、decimal
&&& 这些隐式转换的规则是:任何类型A,只要其取值范围完全包在类型B的取值范围内,就可以隐式转换为类型B。
&&& 2.显式类型转换
但是,仍有许多场合不能进行隐式类型转换,否则编译器会报告错误。例如:
&&&&& byte v1;
&&&&& short v2 = 7;
&&&&& v1 = v2;
&&& 如果编译这段代码,就会产生如下错误:
&&&&& Cannot implicitly convet type ‘short’ to ‘byte’
为了能成功地编译这段代码,需要添加代码,进行显式转换。显式类型转换的一般语法如下:
&&&&& (destinationType) sourceVar
&&& 把sourceVar中的值转换为destinationType。
&&& 同时,这也是一种比较危险的操作。比如在从long转换为int的过程中,如果long变量的值比int类型的最大值还大,就会出现问题。例如:
&&&&& long val = ;
&&&&& int i = (int)
&&& 结果为:
&&&&& i = -
出现这样的结果的原因在于,把一个数据类型显式转换为另一种数据类型的过程中,有些数据位丢失了。显然,这不是我们所期望的,那如何确定何时会出现这样的情况呢?C#提供了两个关键字checked和unchecked,用来测试操作是否会产生溢出。使用方式如下:
&&&&& checked (expression)
&&&&& unchecked (expression)
&& &使用checked运算符可以检查数据类型转换是否安全,如果不安全,就会在运行时抛出一个溢出异常(第3章中将介绍异常)。上面的例子可改写为:
&&&&& long val = ;
&&&&& int i = checked ((int) val);
需要注意的是:显式转换也有一些限制。彼此之间没有什么关系的类型不能进行数据类型转换。例如值类型,只能在数字、char类型和enum类型之间转换。不能直接把bool类型转换为其他类型,也不能把其他类型转换为bool类型。
&&& 3.字符串转换
数字和字符串之间的转换,不能使用显式类型转换,系统也不会进行隐式类型转换,而是通过.NET类库提供的方法。把一个变量转换为字符串,需要调用一个名为ToString的方法:
&&&&& int i = 10;
&&&&& string s = i.ToString();
&&& 同样,把一个字符串转换为一个数字或bool值,可以使用Parse方法:
&&&&& string s = “100”;
&&&&& int i = Int32.Parse(s);
&&& 如果不能进行转换(例如把字符串hello转换为一个整数),Parse方法就会抛出一个日常。
&&& System名空间还有一个Convert类,前面的例子中就使用了Convert.ToDouble等命令把字符串值转换为数值,显然,这种方式并不适合于所有的字符串。为了成功执行这种类型的转换,所提供的字符串必须是数值的有效表达式,该数值还必须是不会溢出的数。以这种方式可以进行许多显式转换,如表2.10所示。
表2.10 Convert类显式转换
Convert.ToBoolean(val)
将val转换为等效的布尔值。
Convert.ToByte(val)
将val转换为8位无符号整数。
Convert.ToChar(val)
将val转换为Unicode字符。
Convert.ToDecimal(val)
将val转换为Decimal数字。
Convert.ToDouble(val)
将val转换为双精度浮点数字。
Convert.ToInt16(val)
将val转换为16位有符号整数。
Convert.ToInt32(val)
将val转换为32位有符号整数。
Convert.ToInt64(val)
将val转换为64位有符号整数。
Convert.ToSByte(val)
将val转换为8位有符号整数。
Convert.ToSingle(val)
将val转换为单精度浮点数字。
Convert.ToString(val)
将val转换为其等效的String表示形式。
Convert.ToUInt16(val)
将val转换为16位无符号整数。
Convert.ToUInt32(val)
将val转换为32位无符号整数。
Convert.ToUInt64(val)
将val转换为64位无符号整数。
&&& 其中val可以是各种类型的变量,这些转换不管是否使用checked,总是要进行溢出检查。
下面的例子用来说明本节介绍的多种类型转换。
&&&&& using S
&&&&&& & class Class1
&&&&&& & {
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& short shortResult,shortVal = 4;
&&&&&&&&&&&&&&&&&&&& int integerVal = 67;
&&&&&&&&&&&&&&&&&&&& long longR
&&&&&& &&&&&&&&&&&&& float floatVal = 10.5F;
&&&&&&&&&&&&&&&&&&&& double doubleResult,doubleVal = 99.999;
&&&&&&&&&&&&&&&&&&&& string stringResult, stringVal = &17&;
&&&&&&&&&&&&&&&&&&&& bool boolVal =
&&&&&&&&&&&&&&&&&&&& doubleResult = floatVal * shortV
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Inplicit:{0} * {1} -&
{2}&,floatVal,shortVal,doubleResult);
&&&&&&&&&&&&&&&&&&&& shortResult = (short)floatV
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Explicit:
{0}-&{1}&,floatVal,shortResult);
&&&&&&&&&&&&&&&&&&&& stringResult= Convert.ToString(boolVal)
+ Convert.ToString(doubleVal);
&&&&&&&&&&&&&&&&&&&&
Console.WriteLine(&Explicit:\&{0}\&+\&{1}\&-&{2}&,
boolVal,doubleVal,stringResult);
&&&&&&&&&&& longResult = integerVal +
Convert.ToInt64(stringVal);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Mixed:{0}+{1}
-&{2}&,integerVal,stringVal,longResult);
&&&&&&&&&&&&& }
&&&&&& & }
&&& 结果输出如下:
&&&&& Implict: 10.5 * 4 -& 42
&&&&& Explict: 10.5 -& 10
&&&&& Explict: “True” + “99.999” -& True99.999
&&&&& Mixed: 67 + 17 -& 84&&&
命名空间是一个比较重要的主题,它们提供了一种组织相关类和其他类型的方式,是.NET中提供的应用程序代码容器。使用命名空间,就可以唯一地标识该命名空间下的代码及其内容。
&&& 在默认情况下,C#代码包含在全局命名空间中。这意味着对于包含在这段代码中的项目,只要按照名称进行引用,就可以由全局命名空间中的其他代码访问它们。如果在该命名空间的外部使用命名空间中的名称,就必须写出该命名空间中的限定名称。限定名称包括所有的继承信息,在不同的命名空间之间使用点字符(.)。例如:
&&&&& namespace LevelOne
& public class NameOne
&&& //code for class NameOne
&&& 这段代码中定义了一个命名空间LevelOne,和该命名空间中的一个类名NameOne。在命名空间LevelOne中可以直接使用“NameOne”来引用,但在全局命名空间必须使用“LevelOne.NameOne”来引用这个名称。
也可以在命名空间中嵌套其他命名空间,为类型创建层次结构。例如:
&&&&& namespace LevelOne
&&&&&&& //code in LevelOne namespace
&&&&&&& namespace LevelTwo
&&&&&&&&& //code in LevelOne.LevelTwo namespace
&&&&&&&&& class NameTwo
&&&&&&&&& {
&&&&&&&&&&& //code for class NameTwo
&&& 其中,在全局命名空间中,NameTwo必须引用“LevelOne.LevelTwo.NameTwo”,在LevelOne命名空间中,则可以引用为“LevelTwo.NameTwo”,在LevelOne.LevelTwo命名空间中,则可以引用为NameTwo。
& &&2.1.5.1using语句
建立命名空间之后,会发现命名空间相当长,键入非常繁琐。这时就可以使用using语句来简化。即在文件的顶部列出类的命名空间,前面加上using关键字。在文件的其他地方,就可以使用其较短的相对名称来引用命名空间。例如,在下面的代码中,LevelOne命名空间中的代码可以访问LevelOne.LevelTwo命名空间中的名称:
&&&&& namespace LevelOne
&&&&&&& using LevelT
&&&&&&& namespace LevelTwo
& class NameTwo
& //code for class NameTwo
&&& LevelOne命名空间中的代码现在可以简单地使用“NameTwo”引用LevelTwo.NameTwo。
&& &2.1.5.2命名空间的别名
在不同的命名空间中,可以定义相同的名称。例如:
&&&&& namespace LevelOne
&&&&&&& class NameThree
&&&&&&&&& //code for class NameThree
namespace LevelTwo
& class NameThree
&&& //code for class NameThree
定义的LevelOne.NameThree和LevelOne.LevelTwo.NameThree是两个不同的名称,可以独立使用。但如果把两个命名空间都包含在using指令中,就会发生类名冲突,导致系统崩溃。此时,可以为命名空间提供一个别名,上面的例子改写为:
&&&&& namespace LevelOne
&&&&&&& using LT = LevelT
&&&&&&& class NameThree
&&&&&&&&& //code for class NameThree
namespace LevelTwo
& class NameThree
&&& //code for class NameThree
&&& LevelOne命名空间中的代码可以把LevelOne.NameThree引用为“NameThree”,把LevelOne.LevelTwo.NameThree引用为“LT.NameThree”。
我们在前面的学习中,可以发现大多数程序的开始处都有using
S语句,因为System命名空间是.NET
Framework应用程序的根命名空间,包含控制台应用程序所需要的所有基本功能。
语句是定义了某项指令的有效的C#表达式。一个实际的程序应当包含若干条语句。
&&& C#中最短小的语句是空语句。空语句什么也不做,它只由一个分号构成:
每条语句通常是独立一行的代码。但是,C#并不强求这种布局格式。只要每条语句之间用一个分号隔开,C#就认为是一条语句。例如:
&&&&& MyVariable = 123; MyVariable +=234;
可以用花括号把一些语句括起来成为语句块(或复合语句)。在编写函数的代码时,经常会用到语句块。函数的所有语句都包含在―个语句块中。例如:
&&&&& public static void Main()
& System.Console.WriteLine (&Hello!&);
C#对一个语句块中的语句数量不加任何限制。
下面将介绍C#语言的核心――流程控制语句。
选择语句可以根据条件是否满足来选择下一步要执行哪些代码。其中的条件使用布尔逻辑,对测试值与一个或多个可能的值进行比较。据此,C#有两种分支代码的结构:if语句和switch语句。
&& if语句使用一个可求出布尔值的表达式作为条件。最简单的语法如下:
if (&test&)
&statement&;
先执行&test&,如果&test&的值为true,就执行语句&statement&;,如果&test&的值为false,则不执行&statement&,例如:
&&&&& if (MyVariable == 123)
&&&&&&& System.Console.WriteLine(“My Variabld’s value is
在上面的示例中,将MyVariable变量的值与字面值123进行比较。如果该变量的值等于123,则表达式MyVariable
== 123的值为true,并会在控制台上显示消息“MyVariable's
value is l23”。如果该变量值不等于123,则表达式MyVariable
== 123的值为false,并且在控制台上不会显示任何消息。
&&& if语句后面也可以用e1se子句。当if语句的布尔表达式的值为false时,将执行e1se关键字后面的语句:
&&&&& if (&test&)
&&&&&&& &statement1&;
&&&&& else
&&&&&&& &statement2&;
&&& 例如:
if (MyVariable == 123)
&&&&&&& System.Console.WriteLine(&MyVariable's value is
&&&&&&& System.Console.WriteLine(&MyVariable's value is not
在上面的示例中,将MyVariable变量的值与字面值123进行比较。如果该变量的值等于123,则并会在控制台上显示消息“MyVariable's
value is l23”。如果该变量值不等于123,则会在控制台上显示消息“MyVariable's
value is not l23”。
else子句后面还可以有它自己的if子句,测试多个条件,语法形式如下:
& if (&test1&)
&&& &statement1&;
& else if (&test2&)
&&& &statement2&;
& else if (&test3&)
&&& &statement3&;
& else if (&testm&)
&&& &statementm&;
&&& &statementn&;
if (MyVariable == 123)
&&&&&&& System.Console.WriteLine(&MyVariable's value is
else if (MyVariable == 124)
&&&&&&& System.Console.WriteLine(“MyVariable's value is
&&&&&&& System.Console.WriteLine (“MyVariable's value is not
&&& 在if和else后面只允许含一条语句,如下列代码所示:
&&&&& if (MyVariable == l23)
&&&&&&& System.Console.WriteLine(“MyVariable's value is
&&&&& System.Console.WriteLine(“This always prints.”);
&&& 上述程序写出“This
always prints”的语句总会执行,因为这条语句不属于if子句,所以不管MyVariable变量的值是否是123,它都会执行。惟一依赖于MyVariable变量值与123的比较结果的语句是写出“MyVariable's
value is 123”的语句。如果要将多个操作语句与一个if或else子句关联起来,就要使用语句块,例如:
if (MyVariable == 123)
System.Console.WriteLine(&MyVariable's value is 123.&);
System.Console.WriteLine(&This prints if MyVariable ==
2.switch语句
&&& switch是多分支选择语句,它可以将一个测试变量与多个值进行比较,而不是仅测试一个条件。但这种测试仅限于离散值。switch语句的基本结构如下:
&&& switch (&testVar&)
&&&&& case &comparisonVar1&:
&&&&&&& &statement1&;
&&&&& case &comparisonVar2&:
&&&&&&& &statement2&;
&&&&& case &comparisonValn&:
&&&&&&& &statementn&;
&&&&& default:
&&&&&&& &statementdefault&;
先求出表达式&testVar&的值,并将这个值与每个&comparisonx&的值进行比较,如果有一个&comparisoni&的值等于&testVar&的值,就执行该case子句中&statementi&;如果没有一个与其相等,就执行default部分的语句。在case语句中,不需要使用大括号把语句组合成语句块,只需要使用break关键字标记每个case代码的结束。
switch语句中使用的表达式&testVar&的值必须为或是可以隐式转换下列类型之一:sbyte、byte、short、ushort、int、uint、long、ulong、char、string。
case关键字后面的表达式&comparisoni&必须是一个常量表达式――不允许使用变量。
&&& 下面的switch语句测试MyVariable变量的值:
switch(MyVariable)
&case 123:
&&&&&&& System.Console.WriteLine(&MyVariable == 123&);
&case 124:
&&&&&&& System.Console.WriteLine(&MyVariable == 124&);
&case 125:
&&& &&&&System.Console.WriteLine(&MyVariable == 125&);
&& C#允许将多个case语句放在一起,其后加一行代码,实际上是一次检查多个条件。如果满足这些条件众的任何一个,就会执行代码。这样就可以在多种情况下都执行相同的语句了。例如:
switch (MyVariable)
&&&&&& case 123:
&&&&&& case 124:
&&&&&&&& System.Console.WriteLine(&MyVariable == 123 or
&&&&& case 125:
&&&&&&& System.Console.WriteLine(&MyVariable == 125&);
在switch语句中是否使用default关键字是可选的。
循环就是重复执行一些语句。在许多问题中都需要用到循环控制,例如,要输入全校学生成绩;求若干个数之和等。在这些问题中,涉及许多相同或相似的代码,如果按顺序书写,就会变成一件非常痛苦的事情。这时使用一个循环就可以指定指令需要执行的次数,大大方便了我们。
&&& C#提供了4种不同的循环机制:for、while、do…while、foreach。让我们首先从简单一些的循环(一直循环到给定的条件满足为止)开始。
1.while语句
其一般形式如下:
& while(&test&)
&statements&;
只要while表达式&test&的值为true,while语句就执行嵌入在其中的语句&statements&。例如:
&&&&& int MyVariable = 0;
&&&&& while(MyVariable & 10)
&&&&&&& System.Console.WriteLine(MyVariable);
&&&&&&& MyVariable++;
上述代码在控制台上打印出下列内容:
2.do…while语句
&&& do…while循环是while循环的后测试版本,即该循环的测试条件要在执行完循环体之后进行。其结构为:
&&&&&&& &statements&;
}while(&test&);
它是这样执行的:先执行一次循环体语句&statements&,然后判别表达式&test&,当表达式&test&的值为true时,返回重新执行循环体语句&statements&,如此反复,直到表达式&test&的值为false为止。例如:
int MyVariable = 0;
&& System.Console.WriteLine(MyVariable);
&&&&&&& MyVariable++;
} while(MyVariable & 10)
上述代码在控制台上打印出下列内容:
&&& while语句循环体执行的次数为零次或多次。如果while语句中布尔表达式的值为false,就不会执行嵌入循环体语句。例如:
int MyVariable = 100;
&&&&& while(MyVariable & 10)
&&&&&& System.Console.WriteLine(MyVariable);
&&&&&& MyVariable++;
&&& 因为while语句中的布尔表达式MyVariable&10的值在第一次执行时就为false,所以在控制台上不会打印出任何内容。因为一开始这个布尔表达式的值就为false,所以从未执行过其中嵌入的语句。
&&& 如果要确保至少执行一次嵌入语句,可以使用do语句,如下列代码所示:
int MyVariable = 100;
&&&&&& System.Console.WriteLine(MyVariable);
&&&&&& MyVariable++;
} while(MyVariable & 10)
上述代码将在控制台上打印出下列内容:
3.for语句
&&& for语句是循环语句中功能最强大的语句,不仅可以用于次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况。for语句中的控制代码包含三部分:
&&& ● 初始化设置,设置for语句循环计数器的起始条件
&&& ● 循环执行条件,指定使for语句执行的布尔表达式
循环变量的增减量,指定每次在嵌入循环语句执行之后对计数器执行的语句
&&& 例如,如果要在循环中,使计数器从1递增到10,递增量为1,则起始值为1,条件是计数器小于或等于10,在每次循环的最后,要执行的操作是给计数器加1。
&&& for循环的语法如下:
&&&&& for(&initializer&;&condition&;&iterator&)
&&&&&&& &statements&;
以下面简单的for循环为例:
for(MyVariable = 0; MyVariable & 10; MyVariable++)
&&& System.Console.WriteLine(MyVariable);
上述for循环中的循环变量是MyVariable,它的初始值是0,接着测试MyVariable&10是否满足。因为这个布尔表达式的值为true,所以执行for循环中的嵌入语句,显示值0。然后执行MyVariable++。当MyVariable的值为10时,循环结束。所有这些指令在控制台上打印出下列内容:
for循环中初始化设置、循环执行条件和循环变量的增减量三部分都是可选的。如果不使用其中的某部分,只需写一个分号而不用指定这部分的语句。下列代码是合法的,它与上述代码等价:
int MyVariable = 0;
for( ; MyVariable & 10; MyVariable++)
&&& System.Console.WriteLine(MyVariable);
下述代码也与原来的代码等价:
for(MyVariable = 0; MyVariable & 10; )
&&& System.Console.WriteLine(MyVariable);
&&& MyVariable++;
当省略for循环的循环执行条件部分时,要格外小心。
因为foreach循环涉及到集合的概念,我们将在下一节再进行介绍。&
C#提供了许多可以立即跳转到程序中另一行代码的语句,包括4个命令:
1.goto语句
&&& goto语句可以直接跳转到程序中用标签指定的位置(标签是一个标示符,后跟一个冒号)。例如:
&&&&& int i=1;
&&&&& while (i &= 10)
&&&&&&& if (i == 6)
&&&&&&&&& goto Label1;
&&&&&&& System.Console.WriteLine(&{0}&, i++);
System.Console.WriteLine(&This code will never be reached.&);
& System.Console.WriteLine(“This code is run when the loop is
exited using goto.”);
&&& goto语句有两个限制。不能使用goto语句从外部进入循环体;不能跳出类的范围和try…catch后面的finally块。
&& &如果希望代码易于阅读和理解,最好不要使用goto语句。
2.break语句
&&& 我们在前面的switch语句中,使用break语句来退出某个case语句。实际上,break语句可退出任何循环,继续执行循环后面的语句。例如:
&&&&& int i = 1;
&&&&& while (i &= 10)
&&&&&&& if ( i == 6)
&&&&&&& System.Console.WriteLine(“{0}”, i++);
&&& 这段代码输出1~5的数字。
&&& 如果把break语句放在嵌套的循环中,它只能结束所在的内部循环,然后执行内部循环后的语句。不能把break放在switch语句或循环体外部。
3.continue语句
&&& continue语句类似于break,也必须用于循环体中。但它终止的是当前的循环,然后继续执行下一次循环,而不是退出循环。例如:
&&&&& for (i = 1; i &= 10; i++)
&&&&&&& if ((i % 2) == 2)
&&&&&&& System.Console.WriteLine(i);
&&& 在这个例子中,当i除以2的余数是0,continue语句就会执行,终止当前的循环,所以这段代码仅显示1、3、5、7、9。
4.return语句
&& return语句用于退出循环及其包含的函数,参见2.4节。
复杂的变量类型
&&& 除了前面看到的简单变量类型,C#还提供3个略复杂但非常有用的变量类型。
如果一个变量只有几种可能的值,就可以定义为枚举类型。所谓“枚举”是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围之内。例如:orientation类型变量的值可以为north,south,east或west中的一个。
在声明一个枚举时,要指定该枚举可以包含的一组可接受的实例值。不仅如此,还可以给值指定易于记忆的名称。对于上面的例子,我们就可以定义一个orientation枚举类型,它可以从上述的4个值中选择一个值。
枚举可以使用enum关键字来定义,语法如下:
& enum typeName
&&& value1,
&&& value2,
&&& value3,
&&& valuen
需要注意的是这里声明和描述的一个用户定义的类型,使用时需再声明这个类型的变量。语法如下:
&&&&& typeName varN
&&& 并赋值为:
&&&&& varName = typeName.
例如,orientation类型定义如下:
&&&&& enum orientation
&&&&&&& north,
&&&&&&& south,
&&&&&&& east,
&&&&&&& west
orientation varOrien =
&&& 其中north、south、east、west称为枚举元素。它们是用户定义的标示符,这些表示符并不自动地代表什么。例如,north不会自动代表“北”。用什么标示符代表什么含义,完全由程序员决定,并在程序中作相应的处理。
&&& 在默认情况下,枚举使用int类型来存储,即枚举类型中的每一个值对应int类型的一个值。除此之外,枚举的基本类型还可以是byte,sbyte,short,ushort,uint,long和ulong。
在默认情况下,每个枚举元素都会按定义时的顺序,从0开始自动赋值。在上面的例子中,north的值为0,south的值为1,east的值为2等。也使用“=”运算符来可以改变枚举元素的值:
& enum typeName : underlyingType
&&& value1 = actualVal1,
&&& value2 = actualVal2,
&&& value3 = actualVal3,
&&& valuen = actualValn
另外,还可以使用一个值作为另一个枚举的基础值,为多个枚举指定相同的值:
&&&&& enum typeName : underlyingType
& value1 = actualVal1,
& value2 = value1,
& valuen = actualValn
没有赋值的枚举元素都会自动获得一个初始值,该值为最后一个明确声明值大1开始的序列。上面代码中,value3的值是value1+1。
下面的例子用于说明枚举类型的使用。
&&&&& using S
enum orientation:byte
&&&&&& & {
&&&&&&&&&&&&& north = 1,
&&&&&&&&&&&&& south = 2,
&&&&&&&&&&&&& east = 3,
&&&&&&&&&&&&& west = 4
&&&&&& & }
&&&&&& & class Class1
&&&&&& & {&&&&&&&&
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& byte directionB
&&&&&&&&&&&&&&&&&&&& string directionS
&&&&&&&&&&&&&&&&&&&& orientation myDirection =
orientation.
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&myDirection =
{0}&,myDirection);
&&&&&&&&&&&&&&&&&&&& directionByte = (byte)myD
&&&&&&&&&&&&&&&&&&&& directionString =
Convert.ToString(myDirection);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&byte equivalent =
{0}&,directionByte);
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&string equivalent =
{0}&,directionString);&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }
&&& 程序运行结果为:
&&&&& myDirection = north
&&&&& byte equivalent = 1
&&&&& string equivalent = north
&&& 这段代码定义了一个枚举类型orientation,创建该类型的变量并赋值,最后输出到屏幕上。并使用显式类型转换把枚举类型转换为byte类型,虽然byte是orientation的基本类型,仍必须使用显式转换。要获得枚举的字符串值,可以使用Convert.ToString()或者变量本身的ToString()方法(myDirection.ToString())。
如果要把byte类型转换为orientation,也需要进行显式转换。但要注意不是每个byte类型变量的值都对应一个orientation的值。例如把byte类型变量myByte转换为orientation,并把这个值赋给myDirection。代码如下:
 myDirection =
(orientation)myB
另外,也可以把string转换为枚举值,方式如下:
&&&&& (enumerationType)Enum.Parse(typedof(enumerationType),
enumerationValueString);
其中Enum.Parse()是静态方法,这个方法带2个参数,第一个参数是要使用的枚举类型。使用typeof运算符可以得到操作数的类型。第二个参数是要转换的字符串。对orientation类型使用这个方法如下:
 string myString =
“north”;
& orientation myDirection =
(orientation)Enum.Parse(typeof(orientation), myString)&;
&&& 同样,也不是所有的字符串值都能转换为orientation。
下面要介绍的变量类型是结构。结构是由几个不同类型的数据组成的数据结构。例如,需要存储从出发地到目的地的路线,该路线由一个方向和一个距离组成。为了简化起见,假定该方向为上一节中定义的orientation枚举,距离值可以用一个double类型的值表示。把它们当作一对来处理,要比单个处理方便一些。
结构体用关键字struct来定义,语法如下:
&&&&& struct &typeName&
&& &&&&&&memberDelarations&
&&& &memberDelarations&包含变量――结构数据成员的声明,每个成员的声明采用如下格式:
&&&&& &accessibility& &type& &name&;
&&& 关于&accessibility&修饰符将在第3章中介绍。这里只需了解要让调用结构的代码访问该结构的数据成员,就使用public关键字。像上面的例子,可写成下面的代码:
&&&&& struct route
&&&&&&& public o
&&&&&&& public double distance&;
定义了结构类型之后,就可以定义该类型的变量:
&&&&& route myR
&&& 通过“.”成员运算符可以访问该变量的数据成员:
&&&&& myRoute.direction = orientation.
&&&&& myRoute.distance = 2.5;
下面的例子用于说明结构使用:
   using S
   enum orientation:byte
&&&&&&  {
&&&&&&&&&&&&& north = 1,
&&&&&&&&&&&&& south = 2,
&&&&&&&&&&&&& east = 3,
&&&&&&&&&&&&& west = 4
&&&&&&  }
&&&&&&  struct
&&&&&&  {
&&&&&&&&&&&&& public o
&&&&&&&&&&&&& pu
&&&&&&  }
&&&&&&  class
&&&&&&  {
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& route myR
&&&&&&&&&&&&&&&&&&&& int myDirection = -1;
&&&&&&&&&&&&&&&&&&&& double myD
&&&&&&&&&&&&&&&&&&&&
Console.WriteLine(&1)North\n2)South\n3)East\n4)West&);
&&&&&&&&&&&&&&&&&&&& do
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Select a
direction:&);
&&&&&&&&&&&&&&&&&&&&&&&&&&& myDirection =
Convert.ToInt32(Console.ReadLine());
&&&&&&&&&&&&&&&&&&&&
}while((myDirection&1)||(myDirection&4));
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Input a distance:&);
&&&&&&&&&&&&&&&&&&&& myDistance =
Convert.ToDouble(Console.ReadLine());
&&&&&&&&&&&&&&&&&&&& myRoute.direction =
(orientation)myD
&&&&&&&&&&&&&&&&&&&& myRoute.distance = myD
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&myRoute specifies a
direction of {0} and a&+&
        distance of
{1}&,myRoute.direction,myRoute.distance);&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&  }
&&&&&&  }
  假设选择方向为East,距离值为40.3,输出如下:
Select a direction:
Input a distance:
myRout specifies a direction of east and a distance of 40.3
结构和枚举一样,都是在主函数外面声明的。处理route的成员的方式与成员类型相同的变量完全一样。
在许多方面,可以把C#中的结构看作是缩小的类。它们基本上与类相同,但更适合于把一些数据组合起来的场合。它与类的区别将在第3章中介绍。
数组是有序数据的集合。数组中的每一个元素都属于同一个数据类型。用一个统一的数组名和下标来唯一地确定数组中的元素。例如,一个班有30个学生,可以用student1,student2,student3,…,student30来表示30个学生的姓名。但这看起来很费时费力。如果采用数组:student是数组名,下标代表学生的序号。比如student[15]代表第15个学生的姓名,就可以和循环结合起来,有效地处理大批量的数据,大大地提高工作效率。
1.一维数组
一维数组的定义如下:
& &baseType&[] &name&;
其中,&baseType&可以是任何变量类型。变量类型后面的方括号不能丢。例如,int表示一个整数,而int[]表示一个整型数组:
数组在使用前必须初始化。初始化方式有两种:以字面值形式指定数组的所有内容;指定数组大小,再使用关键字new初始化所有的数组元素。
使用字面值指定数组时,只需要将数组元素的字面值用逗号分隔开,依次放在一对大括号内。例如:
& int myIntArray = {5, 9, 10, 2, 99};
其中,myIntArray有5个元素,每个元素都被赋予了一个整数值。
而使用new关键字,需在类型名后面的方括号中给出大小:
int[] myIntArray = new int[5];
这里使用一个常量定义数组大小,每个数组元素会被赋予同一个默认值,对于数值型来说,其默认值是0。也可以使用这两种方式的组合来进行初始化。例如:
& int[] myIntArray = new int[5]{5, 9, 10, 2, 99};
使用这种方式时,数组大小必须与元素个数相匹配,例如,不能编写如下代码:
& int[] myIntArray = new int[10]{5, 9, 10, 2, 99};
同样也不能把过多的值赋予数组。
实际上,C#可以在声明数组时不进行初始化,这样以后就可以在程序中动态地指定其大小。利用这项技术,可以创建一个空引用,以后再使用new关键字把这个引用指向请求动态分配的内存位置:
int[] myIntA
myIntArray = new int[32];
访问数组中的单个元素的方法为
ArrayName[i]
所有的C#数组都用下标0代表第一个数组元素变量:
myIntArray[0] = 35;
同样,用下标值来表示有5个元素的数组中的最后一个元素:
myIntArray[4] = 432;
数组在C#中是一种特殊的类型,有自己的方法。例如可以使用下面的语法查看一个数组包含多少个元素:
int numElements = myIntArray.L&
&&& 如果数组元素是某个预定义类型,可以使用Sort方法把数组元素按升序排列:
&&&&& Array.Sort(myIntArray);
&&& 可以使用Reverse()方法把数组中的元素反序排列:
&&&&& Array.Reverse(myArray);
下面的例子用来说明一维数组的使用:
&&&&& using S
class Class1
&&&&&& & {
&&&&&&&&&&&&& static void Main(string[] args)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& string[] friendNames = {&Robert
Barwell&,&Mike Parry&,&Jeremy Beacock&};
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(&Here are {0} of my
friends:&,friendNames.Length);
&&&&&&&&&&&&&&&&&&&& for(i=0;i&friendNames.Li++)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&&
Console.WriteLine(friendNames[i]);
&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }
&&& 程序输出如下:
&&&&& Here are 3 of my friends:
&& &&&Robert Barwell
&&&&& Mike Parry
&&&&& Jeremy Beacock
&&& 这段代码建立了一个有3个元素的string数组,并用for循环把3个数组元素输出。使用for循环输出数组元素容易出错,造成数组下标越界访问。在C#中提供了另外一种循环,即foreach循环。
2.foreach循环
foreach循环可以迭代集合中的每一项。集合是一种包含其他对象的对象比如C#中的数组、System.Collection命名空间中的集合类,以及用户定义的集合类。从下面的代码中可以了解foreach循环的语法:
&&&&& foreach (&baseType& &name& in &array&)
&&&&&&& //can use &name&for each element
&&& 其中,foreach循环每次迭代数组中的一个元素,依次把每个元素的值放在&baseType&型的变量&name&中,然后执行一次循环。foreach循环不会访问到数组元素以外的内存空间,这样我们不用考虑数组中有多少个元素,就能确保访问倒每个数组元素。使用这个循环改写上面的例子,如下所示:
&&&&& static void Main(string[] args)
&&&&&&& string[] friendNames = {&Robert Barwell&,&Mike
Parry&,&Jeremy Beacock&};
&&&&&&&&&&&&& Console.WriteLine(&Here are {0} of my
friends:&,friendNames.Length);
&&&&&&&&&&&&& foreach(string friendName in friendNames)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& Console.WriteLine(friendName);
&&&&&&&&&&&&& }&&&&&&&&&&&
&&& 这段代码的输出结果与前面的例子完全相同。
注意,foreach循环对数组内容进行只读访问,所有不能改变集合中各项的值,下面的代码不会编译:
&&&&& foreach (int temp in arrayOfInts)
&& temp++;
&& Console.WriteLine(temp);
如果需要迭代集合中的各项,并改变它们的值,就应使用for循环。
3.多维数组
&&& 多维数组是使用多个下标访问其元素的数织。C#支持两种类型的多维数组,第一种是矩形数组,即每行的元素个数都相同。第二种是变长数组,即每行都有不同的元素个数。这里先看下矩形数组。
在二维矩形数组中,每一行有相同的列数,也称为矩阵,可以声明如下:
&&&&& &baseType&[,]&name&;
&&& 多维数组只需要更多的逗号,例如:
&&&&& &baseType&[,,,]&name&;
&&& 这里声明了一个四维数组。
赋值也使用类似于一维数组的语法,但需用逗号分隔开下标。例如要声明和创始化一个二维数组myArray,其基本类型是double,3行4列的矩阵,则需要:
&&&&& double[,] myArray = new double[3, 4];
另外,还可以使用字面值进行初始化。使用嵌套的花括号,用逗号分隔开。例如:
&&&&& double[,] myArray = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4,
要访问多维数组中的每个元素,只需指定它们的下标,并用逗号分隔开即可。例如:
&&&&& myArray[2, 1]
&&& 这个表达式将访问myArray数组的第3行的第2个元素,值为4。需要注意的是下标从0开始。
&&& foreach循环也可以访问多维数组中的所有元素,其方式与一维数组相同,例如:
&&&&& double[,] matrix = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4,
&&&&& foreach(double temp in matrix)
&&&&&&& Console.WriteLine(“{0}”, temp);
4.数组的数组
&&& C#支持的第二种多维数组是变长数组,也叫正交数组,其中每行可以有不同的元素个数。显然,它比矩形数组更灵活,在创建正交数组时也会复杂一些――需要有一个数组,它的每个元素都是另一个数组。即要创建一个数组的数组,但这些数组都必须有相同的基本类型。
声明数组的数组,其语法要在数组的声明中指定多个方括号对,例如:
&&&&& int a[][];
但初始化正交数组不像初始化多维数组那样简单,不能进行这样的声明:
&&& a[][] = new int[3][4];
&&& a[][] = {{1, 2, 3}, {1}, {1,2}};
有两种方式:第一种可以先初始化包含其他数组的数组,然后再初始化子数组:
&&&&& a = new int[3][];
&&&&& a[0] = new int[4];
&&&&& a[1] = new int[3];
&&&&& a[2] = new int[1];
第二种方式是使用字面值赋值的一种改进形式:
&&&&& a = {new int[]{1, 2, 3}, new int[]{1}, new int[]{1,
正交数组也可以使用foreach循环,但通常需要嵌套循环,才能得到实际的数据。假定下述变长数组包含10个子数组,每个子数组又包含一个整数数组如下:
& int[][] myArray = {new int[]{1},
new int[]{1, 2},
new int[]{1, 3},
new int[]{1, 2, 4},
new int[]{1, 5},
new int[]{1, 2, 3, 6},
new int[]{1, 7}
new int[]{1, 2, 4, 8},
new int[]{1, 3, 9},
new int[]{1, 2, 5, 10}};
&&&&& foreach(int[] myIntArray in myArray)
&&&&&&& foreach(int temp in myIntArray)
&&&&&&&&& Console.WriteLine(temp);
&&& 可见,迭代变长数组元素要比矩形数组复杂。
某些功能常常需要在一个程序中执行好几次,例如查找数组中的最大值。如果采用前面介绍的方法,可以把相同的代码块按照需要放在应用程序中,但如果要改动功能代码块,就需要修改多处,并且如果遗忘一处,就有可能发生错误。解决这个问题的方法就是使用函数。
函数的定义与使用
在C#中,函数的定义包括函数的修饰符,然后是返回值的类型,方法名、输入参数的列表。具体语法如下:
&&&&& [modifies] return_type MethodName([paraments])
&&&&&&& //Method body
每个参数都包括参数类型名以及在函数体中的引用名称。如果函数有返回值,函数体内必须有return语句用来返回函数值。如果函数没有返回值,就把返回类型指定为void。如果函数不带参数,仍需要在方法名的后面写上一对空的圆括号。调用函数的方法是函数名后跟括号。例如:&&&&
&&&&& class Program
static void Write()
Console.WriteLine(&Text output from function.&);
&&&&&& static void Main(string[] args)
执行程序,结果如下:
&&&&& Text output from function.
&&& 该代码先定义了函数Write(),然后再主函数中调用它。
1.函数的返回值
通过函数进行数据交换的最简单方式是利用返回值。有返回值的函数会计算这个值,其方式与在表达式中使用变量计算它们包含的值完全相同。与变量一样,返回值也有数据类型。其语法如下:
static &returnType& &functionName&([paraments])
return &returnValue&;
这里&returnValue&必须是一个值,其类型可以是&returnType&,也可以隐式转换为该类型。&returnType&可以是任何类型,包括前面介绍的较复杂的类型。例如:
static double getVal()
&&&&&& return 3.2;
返回值通常是函数执行的一些处理的结果。在执行到return语句时,程序会立即返回调用代码,return语句后面的代码都不会执行。一个函数可以包含多个return语句。例如:
public bool IsPositive(int value)
&&&&&&& if(valaue & 0)
这段程序根据value的值,将返回两个值中的一个。
&&& 注意所有的处理路径都必须执行到
return语句。下面的代码是不合法的:
static double getVal(int checkVal)
double checkV
if (checkVal & 5)
&&&&&&&& return 4.7;
如果checkVal &= 5,就不会执行到return语句。
最后要注意的是,在通过void关键字声明的函数中不能使用return语句。
2.函数参数
在调用函数时,主调函数和被调用函数之间多数都有数据传递,除了上面的返回值之外,还可以使用参数。一般来说,在定义函数时函数名后面括号中的变量称为“形式参数”(简称“形参”),在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”(简称“实参”)。
&&& 有参数时函数定义改写如下:
static &returnType& &functionName&(&paramType& &paramName&,
return &returnValue&;
可以有任意多个参数,每个参数都有一个类型和一个名称。参数用逗号分隔开。每个参数都在函数的代码中用作一个变量。例如,下面是一个简单的函数,带有两个参数,并返回它们的乘积:
static double product(double param1, double param2)
return param1 * param2;
&&& 在Main()函数中调用它,使用以下代码:
&&&&&& product(2.3, 3.2);
&&& 在这个程序中,param1和param2是形参,而2.3和3.2是实参,实参除了是常量之外,还可以是变量或表达式,但要求有确定的值。在调用时,将实参的值赋给形参。所以要求实参和形参要匹配,即要匹配参数的类型、个数和顺序。例如,下面的函数:
static void myFunction(string myString, double myDouble)
不能使用下面的代码调用:
myFunction (2.6, &Hello&);
该程序把一个double值作为第一个参数传递,把string值作为第二个参数传递,参数的顺序与函数声明中定义的顺序不匹配。
也不能使用下面的代码:
myFunction(&Hello&);
这里仅传送了一个string参数,而该函数需要两个参数。
中,实参向形参的数据传递都是“值传递”。
其含义是,单向传递,只能由实参传递给形参,而不能由形参传回来给实参,即对形参的任何修改都不影响实参。到目前为止,本章定义的所有函数都是值传递。例如,下面的函数使传递过来的参数值加倍,并显示出来:
static void showDouble(int val)
Console.WriteLine(&val doubled = {0}&, val);
参数val在这个函数中被加倍,如果以下面的方式调用它:
int myNumber = 5;
Console.WriteLine(&myNumber = {0}&, myNumber);
showDouble(myNumber);
Console.WriteLine(&myNumber = {0}&, myNumber);
程序输出如下所示:
&&&&& myNumber = 5
val doubled = 10
myNumber = 5
把myNumber作为一个实参,调用showDouble()并不影响Main()中myNumber的值,即给val形参加倍,myNumber的值也不变。
但如果要改变myNumber的值,可以使用一个给myNumber返回新值的函数,如下:
static void DoubleNum(int val)
并使用下面的代码调用它:
int myNumber = 5;
Console.WriteLine(&myNumber = {0}&, myNumber);
myNumber = DoubleNum(myNumber);
Console.WriteLine(&myNumber = {0}&, myNumber);
但这段代码不能改变用作参数的多个变量值,因为函数只有一个返回值。此时可以通过引用传递参数,即函数形参与函数调用中实参相同,函数引用的形参是实参的一个副本,对这个形参进行的任何改变都会影响实参。为此,需使用数组或其它引用类型进行数据传递。例如:
& class ParameterTest
& static void Function(int[] intArray)
&&& intArray[0] = 100;
public static void Main(string[] args)
& int[] ints = {0, 1, 2, 4, 8};
& Console.WriteLine(“ints[0] = ”+ints[0]);
& Console.WriteLine(“Calling
Function…”&);
& Function(ints);
& Console.WriteLine(“ints[0] = ”+ints[0]);
结果如下:
& ints[0] = 0
& Calling Function…
& ints[100] = 100
可以发现在intArray中改变的值在原来的数组中也改变了。
需要注意的是,字符串是不能改变的,如果要改变字符串的值,系统就会创建一个新的字符串。在函数调用中,对字符串所作的改变都不会影响原来的字符串。
另外,还可以使用ref关键字指定参数为引用参数。即如果把一个实参传递给函数,且这个函数的参数前带有ref关键字,则该函数对形参所作的任何改变都会影响实参的值。例如:
static void showDouble(ref int val)
Console.WriteLine(&val doubled = {0}&, val);
函数调用:
int myNumber = 5;
Console.WriteLine(&myNumber = {0}&, myNumber);
showDouble(ref myNumber);
Console.WriteLine(&myNumber = {0}&, myNumber);
输出如下所示:
myNumber = 5
val doubled = 10
myNumber = 10
这次,myNumber
被showDouble()修改了。
用作ref参数的变量有两个限制。首先,函数可能会改变引用参数的值,所以必须在函数调用中使用变量。所以,下面的代码是非法的:
const int myNumber = 5;
Console.WriteLine(&myNumber = {0}&, myNumber);
showDouble(ref myNumber);
Console.WriteLine(&myNumber = {0}&, myNumber);
其次,必须使用初始化过的变量。在传递参数前,无论是值传递还是引用传递,实参必须初始化。下面的代码是非法的:
showDouble(ref myNumber);
Console.WriteLine(&myNumber = {0}&, myNumber);
3. 参数数组
C#允许为函数指定一个(只能指定一个)特定的参数,这个参数必须是函数定义中的最后一个参数,称为参数数组。参数数组可以使用个数不定的参数调用函数,它可以使用params关键字来定义。参数数组可以简化代码,因为不必从调用代码中传递数组,而是传递可在函数中使用的一个数组中相同类型的几个参数。定义使用参数数组的函数时,需要使用下述代码:
static &returnType& &functionName&(&p1Type& &p1Name&, ...
,params &type&[] &name&)
return &returnValue&;
使用下面的代码可以调用该函数:
&functionName&(&p1&, ... , &val1&, &val2&, ...)
其中&val1&, &val2&等都是类型为&type&的值,用于初始化&name&数组。在可以指定的参数个数方面没有限制,甚至可以根本不指定参数。这一点使参数数组特别适合于为在处理过程中要使用的函数指定其他信息。例如,假定有一个函数GetWord(),它的第一个参数是一个string值,并返回字符串中的第一个单词。
string firstWord = GetWord(&This is a sentence.&);
其中firstWord被赋予字符串This。
可以在GetWord()中添加一个params参数,以根据其下标选择另一个要返回的单词:
string firstWord = GetWord(&This is a sentence.&, 2);
假定第一个单词计数为1,则firstWord就被赋予字符串is。
也可以在第3个参数中限制返回的字符个数,同样通过params参数来实现:
string firstWord = GetWord(&This is a sentence.&, 4, 3);
其中firstWord被赋予字符串sen。
下面例子用于说明定义并使用带有params类型参数的函数。
class Program
static int SumVals(params int[] vals)
int sum = 0;
foreach (int val in vals)
&&&&&&& static void Main(string[] args)
int sum = SumVals(1, 5, 2, 9, 8);
Console.WriteLine(&Summed Values = {0}&, sum);
Console.Readkey();
执行代码,结果如下所示:
& Summed Values = 25
在这个例子中,函数sumVals()的参数使用关键字params定义的,可以接受任意个int参数(或不接受任何参数),这个函数对vals数组中的值进行迭代,把这些值加在一起,返回其结果。在Main()中,用5个整型参数调用这个函数。
4. 输出参数
除了根据引用传递值之外,还可以使用out关键字,指定所给的参数是一个输出参数。out关键字的使用方式与ref关键字相同,除了可以把未初始化的变量用作out参数外。即使调用代码把已初始化的变量用作out参数,在函数执行时也会丢失该变量中的值。
例如,考虑返回数组中最大值并返回最大值元素下标的函数,为了简单起见,如果数组中有多个元素的值都是这个最大值,只提取第一个最大值的下标。程序如下所示:
static int MaxValue(int[] intArray, out int maxIndex)
int maxVal = intArray[0];
maxIndex = 0;
for (int i = 1; i & intArray.L i++)
if (intArray[i] & maxVal)
maxVal = intArray[i];
maxIndex =
return maxV
可以用下述方式使用该函数:
int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2};
Console.WriteLine(&The maximum value in myArray is {0}&,
MaxValue(myArray, out maxIndex));
Console.WriteLine(&The first occurrence of this value is at
element {0}&, maxIndex + 1);
结果输出如下:
&&&&& The maximum value in myArray is 9
The first occurrence of this value is at element 7
注意,必须在函数调用中使用out关键字,就像ref关键字一样。如果在函数体中,没有给out参数分配一个值,那么函数就不能编译。
变量的作用域
变量的作用域是可以访问该变量的代码区域。变量的作用域是一个重要的主题,作用域的确定有以下规则:
●只要变量所属的类在某个作用域内,该变量也在该作用域内。
●局部变量存在于表示声明该变量的语句块结束的大括号之前的作用域内。
●同名的变量不能在相同的作用域内声明两次。
【例2-10】
class Program
static void Write()
string myString = &String defined in Write()&;
Console.WriteLine(&Now in Write()&);
Console.WriteLine(&myString = {0}&, myString);
&&&&&&&& static void Main(string[] args)
string myString = &String defined in Main()&;
Console.WriteLine(&\nNow in Main()&);
Console.WriteLine(&myString = {0}&, myString);
&&&&&&&& }
这段代码结果如下所示:
&& &&&Now in Write()
&&&&& myString = String defined in Write()
&&&&& Now in Main()
&&&&& myString = String defined in Main()
这段代码执行的操作如下:Main()定义和初始化字符串变量myString,调用Write(),Write()定义和初始化一个字符串变量myString,它与Main()中定义的myString变量完全不同,Write()把在Write()中定义的字符串myString输出,返回Main(),Main()把在Main()中定义的myString字符串输出。作用域以这种方式覆盖一个函数的变量称为局部变量,即在一个函数内部定义的变量只在本函数范围内有效,在此函数之外是不能使用这些变量的。同样在一个语句块中定义的变量,只能在本语句块中使用。例如:
& public class ScopeTest
& public static void Main()
&&& for(int i = 0; i & 10; i++)
& &&&&Console.WriteLine(i);
for(int i = 9; i &= 0; i--)
& Console.WriteLine(i);
&&& 这段代码使用一个for循环打印出从0到9的数字,再打印从9到0的数字。由于i是在循环内部声明的,所以变量i对循环来说是局部变量。而下面的程序:
for (i = 0; i & 10; i++)
string text = &Line & + Convert.ToString(i);
Console.WriteLine(&{0}&, text);
Console.WriteLine(&Last text output in loop: {0}&, text);
由于字符串变量text是for循环的局部变量,这段代码不能编译,因为在该循环外部试图使用变量text,这超出了循环的作用域。
一般地,在函数外面定义的变量称为全局变量,其作用域可覆盖几个函数。例如:
【例2-11】
&&&&& class Program
static string myS
&&&&&&& static void Write()
string myString = &String defined in Write()&;
Console.WriteLine(&Now in Write()&);
Console.WriteLine(&Local myString = {0}&, myString);
Console.WriteLine(&Global myString = {0}&, Program.myString);
static void Main(string[] args)
string myString = &String defined in Main()&;
Program.myString = &Global string&;
Console.WriteLine(&\nNow in Main()&);
Console.WriteLine(&Local myString = {0}&, myString);
Console.WriteLine(&Global myString = {0}&, Program.myString);
&&& 结果如下所示:
&&&&& Now in Write()
&&&&& Local myString = String defined in Write()
&&&&& Global myString = Global myString
&&&&& Now in Main()
&&&&& Local myString = String defined in Main()
&&&&& Global myString = Global myString
这里添加了一个全局变量myString,它是类Program的一个字段。在控制台应用程序中,必须使用static
或 const关键字,来定义这种形式的全局变量。如果要修改全局变量的值,就需要使用static,因为const禁止修改变量的值。
为了区分这个变量和Main()与Write()中同名的局部变量,必须用一个完整限定的名称为变量名。这里把全局变量称为Program.myString。注意,在全局变量和局部变量同名时,这是必需的。如果没有局部myString变量,就可以使用myString表示全局变量,而不需要使用Program.myString。如果局部变量和全局变量同名,全局变量就会被屏蔽。
也可以使用这种技术交换数据,但在许多情况下不应使用这种方式。通过下面的代码做进一步的说明:
&&&&& class Program
static void showDouble(ref int val)
Console.WriteLine(&val doubled = {0}&, val);
&&&&&&& static void Main(string[] args)
int val = 5;
Console.WriteLine(&val = {0}&, val);
showDouble(ref val);
Console.WriteLine(&val = {0}&, val);
&&& 和下面的代码比较:
class Program
static void showDouble()
Console.WriteLine(&val doubled = {0}&, val);
&&&&&&& static void Main(string[] args)
Console.WriteLine(&val = {0}&, val);
showDouble();
Console.WriteLine(&val = {0}&, val);
这两个showDouble()函数的结果是相同的,说明两种方法都是有效的。选用哪种取决于以下的一些规则。
首先,使用全局变量,会使函数的通用性降低,因为函数在执行时要依赖于其所在的外部变量。如果全局变量与局部变量同名,则在局部变量的作用范围内,全局变量被屏蔽。另外,全局数据可以在应用程序的任何地方修改,程序容易出错。使用全局变量会降低程序的清晰性,使代码更难理解。
但是,使用全局变量也有好处的。由于一个程序中所有的函数都能引用全局变量的值,相当于各个函数间有直接的传递通道,增加函数间的联系。
总之,可以自由选择使用哪种技术来交换数据。一般情况下,最好使用参数,而不使用全局数据,但有时使用全局数据更合适。
C#程序是从方法Main()开始执行的,即Main()是C#应用程序的入口。这个方法必须是类或结构的静态方法,并且其返回类型必须是int或void。通常会显式指定public修饰符,因为必须在程序外部调用Main()函数,但为该函数指定什么访问级别并不重要,即使把该函数标记为private,它也可以运行。
在C#控制台或Windows应用程序中,如果有多个Main方法,编译器就会返回一个错误,例如:
namespace MainExample
&& class Client
&&&&& public static int Main()
&&&&&&&& MathExample.Main();
&&&&&& &&return 0;
&& class MathExample
&&&&& static int Add(int x, int y)
&&&&&&&& return x +
&&&&& public static int Main()
&&&&&&&& int i = Add(5,10);
&&&&&&&& Console.WriteLine(i);
&&&&&&&& return 0;
上述代码中包含两个类,它们都有一个Main()方法。如果按照通常的方式编译这段代码,就会得到下述错误:
MainExample.cs(7,23): error CS0017: Program 'MainExample.exe'
has more than one entry point defined: ' MainExample.Client.Main()'
MainExample.cs(15,23): error CS0017: Program
'MainExample.exe' has more than one entry point defined: '
MainExample.MathExample.Main()'
但是,可以使用/main选项,其后跟Main()方法所属类的全名(包括命名空间),明确告诉编译器把哪个方法作为程序的入口点:
csc MainExample.cs /main: MainExample.MathExample
给Main()方法传送参数:
Main()函数有一个参数string[]
args,下面将介绍该参数及其使用。
Main()的参数是从应用程序外部接受信息的方法,这些信息在运行期间指定,其形式是命令行参数。这个参数是一个字符串数组,传统称为args(但C#可以接受任何名称)。
下面的例子ArgsExample.cs是在传送给Main方法的字符串数组中循环,并把每个选项的值输出:
【例2-12】
& class ArgsExample
&&&&& public static int Main(string[] args)
&&&&&&&& for (int i = 0; i & args.L i++)
&&&&&&&& {
&&&&&&&&&&& Console.WriteLine(args[i]);
&&&&&&&& }
&&&&&&&& return 0;
通常使用命令行就可以编译这段代码。在运行编译好的可执行文件时,可以在程序名的后面加上参数,例如:
ArgsExample /a /b /c
&&& 程序输出如下:
本章学习了声明变量的方法,使用变量前需初始化以及常量的使用。C#中的预定义数据类型分为值类型和引用类型,其中值类型包括整数、浮点数、字符和布尔类型;引用类型介绍了object类型和string类型。变量和运算符结合起来,就是一个表达式。简单的表达式包括数学运算、比较运算、逻辑运算符、赋值运算、位运算和条件运算等。把数据从一种类型转换为另一种类型即为类型转换。C#提供两种类型转换:隐式类型转换和显式类型转换。
语句是定义了某项指令的有效的C#表达式。一个实际的程序应当包含若干条语句。选择语句可以根据条件是否满足来选择下一步要执行哪些代码。C#有两种分支代码的结构:if语句和switch语句。循环就是重复执行一些语句。C#提供了4种不同的循环机制:for、while、do…while、foreach。C#提供了许多可以立即跳转到程序中另一行代码的语句,包括4个命令:goto、break、continue和return。
如果一个变量只有几种可能的值,就可以定义为枚举类型。在声明一个枚举时,要指定该枚举可以包含的一组可接受的实例值。结构是由几个不同类型的数据组成的数据结构。使用关键字stucture定义。数组是有序数据的集合。数组中的每一个元素都属于同一个数据类型。数组分为一维和多维。多维数组又可分为矩形数组和变长数组。
在C#中,函数的定义包括函数的修饰符,然后是返回值的类型,方法名、输入参数的列表。变量的作用域是可以访问该变量的代码区域。分为局部变量和全局变量。C#程序是从方法Main()开始执行的,利用参数args从应用程序外部接受信息。
下一章将介绍面向对象相关概念和语法。
1.下面哪个不是合法的变量名?
&A.myVariableIsGood
B.99Flake
D.time2GetJiggyWidIt
2.字符串supercalifragilisticexpialidocious是因为太长了而不能放在string变量中吗?为什么?
3.编写一个控制台应用程序,要求用户输入4个int值,并显示它们的乘积。提示:可以考虑使用Convert.ToDouble()命令,该命令可以把用户在控制台上输入的数转换为double;从string转换为int的命令是Convert.ToInt32()。
4.如果两个整数存储在变量val1和val2中,该进行什么样的布尔测试,看看其中的一个(但不是两个)是否大于10?
5.编写一个应用程序,其中包含练习4中的逻辑,让用户输入两个数字,并显示它们,但拒绝接受两个数字都大于10的情况,并要求用户重新输入。
6.下面的代码有什么错误?
&& for(i =1; i &= 10; i++)
&&&& if((i % 2) = 0)
&&& Console.WriteLine(i);
7.下面的转换哪些不是隐式转换?
a) int转换为short
b) short转换为int
c) bool转换为string
d) byte转换为float
8.下面的代码可以成功编译吗7如果不能,为什么?
&& string[] blab = new string[5];
&& string[5] = 5th string.
9.编写一个控制台应用程序,它接收用户输入的一个字符串,将其中的字符以与输入相反的顺序输出。
10.编写一个控制台应用程序,它接收―个字符串,用“yes”替换字符串中所有的“no”。
11.编写一个控制台应用程序,给字符串中的每个单词加上双引号。
12.下面两个函数都有错误,请指出这些错误。
&&&&&&& static bool Write()
Console.WriteLine(&Text output from function.&);
static void myFunction(string label, params int[] args, bool
showLabel)
if (showLabel)
Console.WriteLine(label);
foreach (int i in args)
Console.WriteLine(&{0}&, i);
13.编写一个应用程序,该程序使用两个命令行参数,分别把值放在一个字符串和一个整型变量中,然后显示这些值。
14.修改下面的结构,使之包含一个返回订单总价格的函数。
&&&&&&& struct order
public string itemN
public int unitC
public double unitC

我要回帖

更多关于 iframe实现网页嵌套 的文章

 

随机推荐