用《叩响C#之门》复习C#基础知识 第五章 枚举、结构体和数组
1、枚举类型(Enumeration type)
enum 类型名{枚举项 逗号隔开} 是一种数据类型不是变量,如:
enum WeekDays {Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}
枚举类型的定义代码写在主函数的外面,和主函数并列放置。
每个枚举项都关联一个整数,所以我们可以直接用枚举项关联的整数进行赋值,但必须进行显示转换。必要时我们也可以将枚举项赋值给整数变量,也需要进行显示转换。如:
WeekDays today = WeekDays.Sunday;
today = (WeekDays)6;
Console.WriteLine((int)today);//与Console.WriteLine(Convert.ToInt32(today)); 效果一致
Console.WriteLine("Today is "+today);
输出:
因为每个枚举项都关联一个整数,所以枚举型变量可参与运算和循环。(在过去的学习笔记中发现过这一知识点)
在默认情况下,枚举项关联值类型为int型,也可以为枚举项指定更合适的数据类型。关联值可以是byte、sbyte、short、ushort、int、uint、long、和ulong等类型。方法是在声明后加“:其他类型” 如:
enmu WeekDays:short
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
枚举的好处:使用直观的标识符代替数字,增强了程序的可读性;每个枚举项都关联着一个数字,可以参加计算和循环;枚举变量只能取枚举项的值,有利于编译器检查出非法的赋值,增加了程序的健壮性。同时由于在编译阶段,编译器会把枚举项编译成对应的整数,系统不会造成性能损失。
2、结构体
struct Student
{
public int number;
public string name;
public string sex;
public string birthday;
}
和枚举类型一样,结构体的定义代码应在主函数之外,其实所有定义类型的代码都应在主函数之外。
( 结构体补充知识:
struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征。
结构还可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。
结构可以实现接口,但它们无法继承另一个结构。因此,结构成员无法声明为 protected。
声明结构的默认(无参数)构造函数是错误的。总是提供默认构造函数以将结构成员初始化为它们的默认值。在结构中初始化实例字段也是错误的。
如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当的构造函数。与类不同,结构的实例化可以不使用 new 运算符。如果不使用 new,则在初始化所有字段之前,字段都保持未赋值状态且对象不可用。
对于结构,不像类那样存在继承。一个结构不能从另一个结构或类继承,而且不能作为一个类的基。但是,结构从基类 Object 继承。结构可实现接口,其方式同类完全一样。
与 C++ 不同,无法使用 struct 关键字声明类。在 C# 中,类与结构在语义上是不同的。结构是值类型,而类是引用类型。
综上:当参数类型为int、double等基本类型时,实参和形参之间进行值传递,实参和形参占用不同的内存空间,形参的变化不对实参造成影响。)
示例 1
说明
下面的示例演示使用默认构造函数和参数化构造函数的 struct 初始化。
代码
C# 复制代码
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
C# 复制代码
// Declare and initialize struct objects.
class TestCoOrds
{
static void Main()
{
// Initialize:
CoOrds coords1 = new CoOrds();
CoOrds coords2 = new CoOrds(10, 10);
// Display results:
System.Console.Write("CoOrds 1: ");
System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
System.Console.Write("CoOrds 2: ");
System.Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);
}
}
输出
CoOrds 1: x = 0, y = 0
CoOrds 2: x = 10, y = 10
示例 2
说明
下面举例说明了结构特有的一种功能。它在不使用 new 运算符的情况下创建 CoOrds 对象。如果将 struct 换成 class,程序将不会编译。 (此情况只针对定义了public的成员变量,其他的还是需要在创建对象后才可,如属性)
代码
C# 复制代码
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
C# 复制代码
// Declare a struct object without "new."
class TestCoOrdsNoNew
{
static void Main()
{
// Declare an object:
CoOrds coords1;
// Initialize:
coords1.x = 10;
coords1.y = 20;
// Display results:
System.Console.Write("CoOrds 1: ");
System.Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
}
}
输出
CoOrds 1: x = 10, y = 20
带属性和构造函数的 struct 练习
using System; using System.Collections.Generic; namespace Test { public class Program { static void Main() { Student student1=new Student(0001,"TOM","Male"); student1.Name = "Mike"; Console.WriteLine("{0:####} {1} {2}",student1.Number,student1.Name,student1.Sex); } } public struct Student { private int number; private string name; private string sex; public Student(int numVar,string nameVar,string sexVar) { this.number = numVar; this.name = nameVar; this.sex = sexVar; } public int Number { get { return this.number; } set { this.number = value; } } public string Name { get { return this.name; } set { this.name = value; } } public string Sex { get { return this.sex; } set { this.sex = value; } } } }
3、数组
数组多种定义方式(含直接赋值方式):
1)元素类型 [] 数组名;
2)元素类型 [] 数组名={初始值列表};
3)元素类型 [] 数组名=new 元素类型[元素个数];
4)元素类型 [] 数组名=new 元素类型[]{初始值列表};
5)元素类型 [] 数组名=new 元素类型[元素个数]{初始值列表};
如果只做了申明,没有赋值,如上述的1)和3),赋值如下
对应1) 数组名 = new 元素类型[元素个数];
后面再对数组的元素分别赋值,如 数组名[所在位置索引]=值;
或 数组名 = new 元素类型[]{初始值列表};
对应3) 直接对数组的元素分别赋值,如 数组名[所在位置索引]=值;
foreach循环语句是针对集合的循环语句,数组也可以被看做是个集合,依次从集合里取出元素进行处理。
foreach(元素类型 元素变量 in 数组名)
foreach只能对集合进行读取操作,不能通过元素变量修改数组中元素的值。不要把此处的元素变量和数组中的元素混为一谈。
int[] arrayInt; arrayInt = new int[] { 1,2,3,4,5}; foreach(int i in arrayInt) { Console.WriteLine(i); }
二维数组
例子:
int[,] matrix1 = new int[3,3]{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };//new int[3,3]可以写成new int[,]或者不写 都是可行的
foreach (int arrayLine in matrix)
{
Console.WriteLine(arrayLine);
}
可变数组
int[][] matrix=new int[3][];
matrix[0] = new int[] { 1, 2 };
matrix[1] = new int[] { 3, 4, 5, 6, 7 };
matrix[2] = new int[] { 8, 9, 10 };
可变数组的形式才可以用到双重foreach循环逐行输出,普通二维数组想用双重foreach,必须将形式改为可变数组的形式。
可变数组:
int[][] arrayChange = new int[2][]; arrayChange[0] = new int[] { 1, 2, 3 }; arrayChange[1] = new int[] { 4, 5, 6, 7 }; foreach (int[] line in arrayChange) { foreach (int element in line) { Console.WriteLine(element); } }
int[][] matrix=new int[3][]; matrix[0] = new int[] { 1, 2, 3 }; matrix[1] = new int[] { 4, 5, 6 }; matrix[2] = new int[] { 7, 8, 9 }; foreach (int[] arrayLine in matrix) { foreach (int element in arrayLine) { Console.Write("{0,-6}", element); } Console.WriteLine(); }
注意:此处的int[][]虽然与int[,]看上去一样,int[,] matrix1 = new int[,]{ { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
但两者截然不同,不能将matrix1与matrix相互赋值,在普通形式下,是不能用双重foreach的,也就是说:定义了二维数组后,普通形式下是不认可martix1[0]。这是为什么,存留疑问!