您的位置:首页 > 编程语言 > C#

C#轻松入门(二)数据类型与流程控制

2007-06-07 06:29 417 查看
第二章 数据类型与流程控制
2.1 C#语言概述
2.2 C#数据类型
2.3 C#流程控制语句

2.1 C#语言概述

在C++和Java的基础上设计的。
完全面向对象。

2.2 C#数据类型
分为两类:值类型和引用类型。
值类型:包括基本类型、枚举类型、结构类型。
引用类型:包括类、接口、数组、委托。

特性

值类型
引用类型
变量中保存的内容实际数据 指向实际数据的引用指针
内存空间配置堆栈(Stack)受管制的堆(Managed Heap)
内存需求较少较多
执行效率较快 较慢
内存释放时间点 执行超过定义变量的作用域时 由垃圾回收机制负责回收
可以为null 不可以 可以
2.2.1 值类型
值类型包括整型、浮点型、小数型、布尔型、字符型、结构型、枚举型。
声明一个值类型的语法形式为:
<数据类型名> <变量名>[ = n];
例如:
int a = 100; //声明一个整型变量a,并赋初值为100;
注意,C#不允许使用未初始化的变量。

1.整型 C#提供了九种整型:
sbyte:1字节有符号
byte: 1字节无符号
short: 2字节有符号
ushort: 2字节无符号
int: 4字节有符号,最常用
uint: 4字节无符号
long: 8字节有符号
ulong:8 字节无符号
char:2字节,单个Unicode字符编码,例如:'1'
2.浮点类型
float:4字节浮点数,常用。例如:35.0f
double:8字节浮点数,常用。例如:2.7E+23
3.小数型
即decimal类型,共128个二进制位,具有28至29位十进制有效数字。适用于金融、货币等需要高精度数值的领域
4.布尔型
用bool表示,bool类型只有两个值true和false。
例如:
bool isExist = false;
bool b = (i>0 && i<10);
注意
if(i) j += 10; //错误
if(j = 15) j += 10; //错误
5.字符型
char型,为单个Unicode字符,字符型常量必须用单引号引起来 。
如果是字符串是单个字符的组合,对应的类型为string。string类型的常量用双引号将字符串引起来。
char和string类型的常量均可以使用转义符。
6.结构型
结构是复合值类型
对性能特别关注的情况下,可以考虑使用结构。
凡是使用结构实现的功能,均可以用类实现。
声明struct类型的语法形式为:
[附加声明] [访问修饰符] struct 结构名称[: 实现的接口] 结构体[;]
7.枚举型
枚举(enum)是一组命名常量的集合,称为枚举成员列表。它可以为一组在逻辑上密不可分的整数值提供便于记忆的符号,从而使代码更清晰,也易于维护。
声明enum类型变量的语法为:
[附加声明] [访问修饰符] enum 名称[:数据类型]{ 枚举列表}

2.2.2 引用类型
“引用”指该类型的变量并不直接存储所包含的实际数据,而是存储实际数据的地址。
C#中的引用类型有四种:
类、委托、接口和数组。
1.类
C#的类与Java的类非常相似。个别地方有区别。
类是面向对象编程的基本单位,是一种包含数据成员、函数成员和嵌套类型的数据结构。类的数据成员有常量、域和事件。函数成员包括方法、属性、索引指示器、运算器、构造函数和析构函数。类和结构同样都包含了自己的成员,但它们之间最主要的区别在于:类是引用类型,而结构是值类型。
类支持继承机制,通过继承,派生类可以扩展基类的数据成员和函数方法,进而达到代码重用和设计重用的目的。
2.委托
指引用方法的类型,它实际上相当于C++中的函数指针原型,主要区别是:
委托在C#中是安全的,它允许实例化和调用类的静态方法,也可以调用类的指定实例的方法。在声明委托类型时,只需要指定委托指向的原型的类型,它不能有返回值,也不能带有输出类型的参数。
3.接口
接口是一组包含了方法的数据结构,只有声明部分,没有实现部分。
接口一旦声明,就不要再更改,否则就失去了接口的意义。
4.数组
数组用于存储同一种类型的数据。
数组是一种引用类型,而不是值类型。
数组是按照数组名、数据元素的类型和维数来描述的。
C#中可以有一维数组、多维数组、交错数组
交错数组的实际含义就是指数组的数组。例如:
int[][] jaggedArray3 =
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};
数组的声明语法举例
数组类型 语法 例子
一维数组 数据类型[ ] 数组变量; int[] myArray;
二维数组 数据类型[,] 数组变量; int[,] myArray;
三维数组 数据类型[,,] 数组变量; int[,,] myArray;
交错数组 数据类型[][] 数组变量; int[][] myArray;

数组的使用
访问数组中的元素时,其下标是从0开始索引的。
数组元素可以是任何类型,包括数组类型。
可以使用Length属性获取一维数组的长度,
如果是多维数组,则可以使用GetLength方法确定其某一特定维的长度。
由多种对数组操作的方法,例如Sort和Reverse,可以将数组按照升序或降序排列。
例.使用Sort和Reverse方法对数组排序


using System;


namespace ArrayExample1




...{


class Program




...{


static void Main()




...{


//声明一维数组Artists,并赋初始值;




string[] Artists = ...{ "Leonardo", "Monet", "Van Gogh", "Klee" };


//将数组Artists做升序排列,并输出其结果;


Array.Sort(Artists);


for (int i = 0; i < Artists.Length; i++)




...{


Console.WriteLine(Artists[i]);


}


//将数组Artists做降序排列,并输出其结果;


Array.Reverse(Artists);


for (int i = 0; i < Artists.Length; i++)




...{


Console.WriteLine(Artists[i]);


}


Console.ReadLine();


}


}


}



2.2.3 值类型之间的数据转换
有两种转换方式:
隐式转换与显式转换;
如果是不同值类型之间的转换,可以使用Convert类。
隐式转换
从低精度、小范围的数据类型转换为高精度、大范围的数据类型,可以用隐式转换。
例如:
int k = 1;
long i = 2;
i = k; //隐式转换

显式转换
如:
long k = 5000;
int i = (int)k
所有的隐式转换也都可以采用显式转换的形式来表示。如:
int i = 10;
long j = (long)i;

将大范围类型的数据转换为小范围类型的数据的时候,必须特别谨慎,因为此时有丢失数据的危险。

2.2.4 装箱与拆箱
装箱:将值类型转换为object类型
拆箱:将object类型转换为值类型
2.2.5 运算符与优先级
与C++和Java相同
在C#中,一共有38个常用的运用符,根据它们所执行运算的特点和它们的优先级,为了便于记忆,我将它们归为七个等级:1、单元运算符和括号。2、常规算术运算符。3、位移运算符。4、比较运算符。5、逻辑运算符。6、各种赋值运算符。7、右位(后缀)单元运算符。

1、在这一级中,有++、--(做为前缀)、()、+、-(做为单元运算符)、!、~。这一级中都是单元运算符,除了其中那一对特殊的具有改变任何运算优先级的括号。这此可以看出,在定义表达式中,那些单元运算符的优先级是很高的,可能是因为它们都直接作用于操作数吧。只有两个单元运算符的优先级不在第一级中,它们因为特殊的原因出现在了后面。
2、在常规算术运算符中,有我们经常使用的*、/、%、+、-,因为他们使用得较多,所以也排在较高的位置。
3、这一级是两个特殊的位操作符,<< 和 >>,它们是所有二元操作符中除常规运算符外优先级最高的了,可能是因为与比较运算符、逻辑运算符比起来,这一组操作符进行的还是数值的计算。
4、比较运算符,包括<、>、<=、>=、==、!=,一共六个,这里有一个特点,就小于优先于大于。
5、逻辑运算符,逻辑运算符原本有四种,但用于单元的“非”运算符排在了前面,所以这里面就只有&、^、|,再加上两个补充的用于提高代码效率的运算符&&、||,共有五个。
6、赋值运算符,这一级最多,几乎前面出现过的二元运算符,在这里加上个“=”号就成为一个赋值运算符。首先当然最基本的赋值运算符“=”;然后是常规算术运算符演变来的“*=、/=、%=、+=、-=”,它们的顺序和常规算术符的顺序一样;然后是位移运算符和逻辑运算符,也按它们演变前的顺序排列,为“<<=、>>=、&=、^=、|=”。因为比较运算符所产生的结果的数据类型和它的运算数的数据类型不同,所以它们没有相应的赋值运算符。
7、最后一级,就是那两个最后的单元运算符后缀版的++、--。它们的出现就是为了做为那两个前缀版的==、--的补充(那两个的优先级太高了,人们需要两个优先级不那么高的),以方便设计表达式,所以这两个的优先级当然要排在最后了。

那么,这38个操作符的优先级顺序就可以写成如下了:(无论是横向还是竖向,越靠前优先级越高)
第一级:++、--(做为前缀)、()、+、-(做为单元运算符时)、!、~。
第二级:*、/、%、+、-。
第三级:<<、>>。
第四级:<、>、<=、>=、==、!=。
第五级:&、^、|、&&、||。
第六级:=、*=、/=、%=、+=、-=、<<=、>>=、&=、^=、|=。
第七级:++、--(做为后缀)。

2.3 C#流程控制语句
1、顺序执行
2、分支
3、循环
4、异常捕获
如果一个逻辑块包含两条或两条以上的语句序列,必须使用大括号{}将语句括起来。
2.3.1 条件分支语句
if语句:它的功能是根据布尔表达式的值(true或者false)选择要执行的语句序列,使用时要注意else应和最近的if语句匹配。
常见形式有:
1) 单独使用if语句,不加else语句
if ( 布尔表达式 )
{
布尔表达式为真时执行的语句序列
}
2) if语句和else语句配套使用的单条件测试
if ( 布尔表达式 )
{
布尔表达式为真时执行的语句序列
}
else
{
布尔表达式为假时执行的语句序列
}
3) else块中嵌套if语句的多条件测试
if ( 布尔表达式1 )
{
布尔表达式1为真时执行的语句序列
}
else if ( 布尔表达式2)
{
布尔表达式2为真时执行的语句序列
}
else if ( 布尔表达式3)
{
布尔表达式3为真时执行的语句序列
}
else
{
所有条件均为假时执行的语句序列
}
switch 语句也叫case语句
switch语句与C++和Java均不完全相同。
switch语句常用形式为:
switch (表达式)
{
case 常量表达式1:
语句序列1
case 常量表达式2:
语句序列2
……
[default: 语句序列]
}
常量表达式
switch条件表达式的值和每个case后的常量表达式可以是string、int、char、enum或其它值类型。
语句序列
每个case后的语句序列可以用大括号括起来,也可以不用, 但是每个case块的最后一句一定要是break语句,或者是goto语句。
switch语句的执行顺序
a) 如果switch语句的条件表达式的值和某一个case标记后指定的值相等,则转到该case标记后的语句序列执行;
b)若switch语句的条件表达式的值和任何一个case标记后指定的值都不相等,则跳到default标记后的语句序列执行;
c)若switch语句下面没有default标记,则跳到switch语句的结尾。
注意:
a) 当找到符合条件表达式值的case标记时,如果其后有语句序列,则它只会执行此case块中的语句序列,不会再对其它的case标记进行判断,所以才要求每个语句序列的最后一条语句必须是break语句, 但是有一个情况例外:如果某个case块为空,则会从这个case块直接跳到下一个case块上。
b) 如果case后有语句,则此case的顺序怎么放都无所谓,甚至可以将default子句放到最上面。因此,在一个switch中,不能有相同的两个case标记。
例.使用switch语句,完成对成绩等级的评定


using System;


namespace SwitchExample




...{


public class Program




...{


public static void Main()




...{


Console.Write("请输入成绩:");


//从键盘接收一行字符


string str = Console.ReadLine();


//转换为整型


int i = Int32.Parse(str.Trim());


if (i > 100 || i < 0)




...{


Console.WriteLine("成绩不在0-100范围内");


}


else




...{


switch (i / 10)




...{


case 10:


Console.Write("满分,");


goto case 9;


case 9:


Console.WriteLine("优秀");


break;


case 8:


case 7:


Console.WriteLine("良好");


break;


case 6:


Console.WriteLine("及格");


break;


default:


Console.WriteLine("不及格");


break;


}


}


Console.ReadLine();


}


}


}

2.3.2 循环语句

包括:
for语句,与Java相同
while语句,与Java相同
do-while语句,与Java相同
foreach语句,用于对集合进行操作。
For语句
一般形式为:
for (初始值;循环条件;循环控制)
{
语句序列
}
在Main方法中加入如下代码:


public static void Main()




...{


Console.Clear();


Console.BackgroundColor = ConsoleColor.Blue;


Console.ForegroundColor = ConsoleColor.Red;


Console.Beep();


for (int i = 1; i < 10; i += 2)




...{


Console.SetCursorPosition(40 - i / 2, i);


for (int j = 0; j < i; j++)




...{


Console.Write("*");


}


}


Console.WriteLine();


Console.ReadLine();


} 

   
While语句
一般形式为:
while (条件)
{
语句序列
}
显然,循环体内的程序可能会执行多次,也可能一次也不执行。
do-while
一般形式为:
do
{
语句序列
}while (条件);
与while语句不同的是,do-while语句循环体内的程序至少会执行一次,然后再判断条件是否为true,如果条件为true,则继续循环。
foreach语句
foreach语句用于逐个提取集合中的元素,并对集合中每个元素执行语句序列中操作的场合。foreach语句特别适合对集合(Collection)对象的存取。其一般形式为:
foreach ( 类型 标识符 in 表达式 )
{
语句序列
}
例.使用foreach语句提取Hashtable对象的每个元素


using System;


using System.Collections;


namespace ForeachExample




...{


class Program




...{


public static void Main()




...{


//声明一个Hashtable集合hs,


   //并使用Hashtable.Add方法为其添加带有指定键和值的元素


Hashtable hs = new Hashtable();


hs.Add("001", "str1");


hs.Add("002", "str2");


hs.Add("003", "str3");


//循环显示hs集合的每个元素;


Console.WriteLine("code string");


foreach (string s in hs.Keys)




...{


Console.WriteLine(s + " " + hs[s]);


}


Console.ReadLine();


}


}


}



2.3.3 跳转语句
1.break语句
功能:退出最近的封闭switch、while、do-while、for或foreach语句。
格式:
break;
【例】循环接收和输出键盘输入的每一行的值,当接收的内容为空字符串时退出。


using System;


namespace BreakExample




...{


public class Program




...{


public static void Main()




...{


for (; ; )




...{


Console.Write("请输入一个字符串(直接回车退出):");


string s = Console.ReadLine();


if (s == "") break;


Console.WriteLine("你输入的是: {0}.", s);


}


Console.ReadLine();


}


}


} 

2.continue语句
功能:将控制传递给下一个while、do-while、for或foreach,继续执行下一次循环。
格式:
continue ;
3.goto语句
一般不用。
4.return语句
功能:将控制返回到出现return语句的函数成员的调用方。
格式:
return [表达式];
其中表达式为可选项,如果该函数成员的返回类型不为null,则return语句必须使用表达式返回这个类型的值,否则return语句不能使用表达式。

2.3.5 异常处理

1.try-catch语句
try
{
语句序列
}
catch(异常类型 标识符)
{
异常处理
}
在程序运行正常的时候,执行try块内的程序。如果try块中出现了异常,程序就转移到catch块中执行。
2.try-catch-finally语句
try
{
语句序列
}
catch(异常类型 标识符)
{
异常处理
}
finally
{
语句序列
}
3.throw语句
格式:
throw [表达式];
抛出表达式的值。
注意表达式类型必须是System.Exception或从System.Exception派生的类的类型。
throw也可以不带表达式,不带表达式的throw语句只能用在catch块中,在这种情况下,它重新抛出当前正在由catch块处理的异常。


using System;


namespace TryCatchExample




...{


class Program




...{


static void F()




...{


try




...{


G();


}


catch (Exception err)




...{


Console.WriteLine("方法F中捕获到: " + err.Message);


   // 重新抛出当前正在由catch 块处理的异常err


throw;


}


}


static void G()




...{


throw new Exception("方法G中抛出的异常。");


}


static void Main()




...{


try




...{


F();


}


catch (Exception err)




...{


Console.WriteLine("方法Main中捕获到:" + err.Message);


}


Console.ReadLine();


}


}                        


} 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐