复习时随手记下的笔记,目前包含以下内容:

  • 单选题整理;
  • 控制结构、数组、方法的重载;
  • 类的定义、属性、构造方法;
  • 类的继承、多态;
  • 绘图、文件。

考试题型

  • 单选题10道,每题2分
  • 编程题4道,每题20分
    • 编程题1:控制结构、数组、方法的重载,简单类
    • 编程题2:类的定义、属性、构造方法
    • 编程题3:继承、多态
    • 编程题4:五子棋相关题目

单选题整理

数据类型与表达式

题目1 每个int类型的变量占用____个字节的内存。

  • A. 1
  • B. 2
  • C. 4
  • D. 8

答案:C。

解析:C#中,short映射int16,占16位,2字节;int映射int32,占32位,4字节;long映射int64,占64位,8字节。

题目2 若有定义:

1
int [] x = new int [10] {0, 2, 4, 4, 5, 6, 7, 8, 9, 10};

则数组x在内存中所占字节数是____。

  • A. 10
  • B. 20
  • C. 40
  • D. 80

答案:C。

解析:根据int占4字节,以及x中有10个int类型变量,得知x占40字节。

题目3 以下程序的输出结果是____。

1
2
3
4
5
6
7
8
9
10
using System;

class Example1
{
public static void Main()
{
int a = 5, b = 4, c = 6, d;
Console.WriteLine("{0}", d = a > b ? (a > c ? a : c) : b);
}
}
  • A. 5
  • B. 4
  • C. 6
  • D. 不确定

答案:C。

解析:a > c ? a : c的结果是6,d = a > b ? 6 : b的结果是6。这类题目也可以直接编写代码求解。

题目4 关于结构类型,下列说法哪些是正确的?

  • A. 结构是值类型
  • B. 结构中不允许定义带参数的实例构造函数
  • C. 结构中允许定义析构函数
  • D. 结构中可以定义成员方法,但是方法内不能使用this指针

答案:A。

解析:结构类型是带有数据成员和函数成员的值类型,可以声明带参数的构造函数,但是不能声明默认构造函数(没有参数的构造函数)或析构函数。

输入与输出

题目5 下面对Read()ReadLine()方法的描述,哪些是正确的____。

  • A. Read()方法一次只能从输入流中读取一个字符
  • B. 使用Read()方法读取的字符不包含回车和换行符
  • C. 使用ReadLine()方法读取的字符不包含回车和换行符
  • D. 只有当用户按下回车键时,Read( )ReadLine()方法才会返回

答案:C。

解析:Read()ReadLine()的区别如下:

  • Read()只能读取一个字符,且返回ASCII值;
  • ReadLine()可以读取一行字符串,返回字符串,但是不包含回车和换行符。

题目6 下面对Write()WriteLine()方法的描述,哪些是正确的____。

  • A. WriteLine()方法在输出字符串的后面添加换行符
  • B. 使用Write()输出字符串时,光标将会位于字符串的后面
  • C. 使用Write()WriteLine()方法输出数值变量时,必须要先把数值变量转换成字符串
  • D. 使用不带参数的WriteLine()方法时,将不会产生任何输出

答案:C。

解析:Write()WriteLine()的区别如下:

  • Write()只输出字符串,当语句执行完毕时,光标位于输出字符串的最后一个字符后;
  • WriteLine()将字符串与换行控制字符一起输出,当语句执行完毕时,光标会移到字符串的下一行。

枚举类型

题目7 下列程序的执行结果是____。

1
2
3
4
5
6
7
8
9
10
using System;

class Example1
{
enum team {my, your = 4, his, her = his + 10};
public static void Main()
{
Console.WriteLine(“{0}, {1}, {2}, {3}”, (int)team.my, (int)team.your, (int)team.his, (int)team.her);
}
}
  • A. 0 1 2 3
  • B. 0 4 0 10
  • C. 0 4 5 15
  • D. 1 4 5 15

答案:C。

解析:在枚举类型中声明的第一个枚举成员的默认值为零,以后的枚举成员值是将前一个枚举成员的值加一得到的。

题目8 以下对枚举的定义,正确的是____。

  • A. enum a = {one, two, three};
  • B. enum a {a1, a2, a3};
  • C. enum a = {‘1’, ’2’, ’3’};
  • D. enum a {“one”, ”two”, ”three”};

答案:B。

解析:枚举类型的声明如下:

1
2
3
4
访问修饰符 enum 枚举名: 基础类型
{
枚举成员
}

其中枚举成员的命名要求与变量一致。

题目9 枚举型常量的值不可以是____类型

  • A. int
  • B. long
  • C. ushort
  • D. double

答案:D。

解析:枚举类型的基础类型必须是八种整型之一,默认为int

数组

题目10 有定义语句:

1
int [,] a = new int[5,6]; 

则下列正确的数组元素的引用是____。

  • A. a(3,4)
  • B. a(3)(4)
  • C. a[3][4]
  • D. a[3,4]

答案:D。

题目11 下列的数组定义语句,不正确的是____。

  • A. int a [] = new int [5] {1, 2, 3, 4, 5};
  • B. int [,] a = new int [3][4];
  • C. int [][] a = new int [3][];
  • D. int [] a = {1, 2, 3, 4};

答案:B。

题目12 类MyClass 中有下列方法定义:

1
2
3
4
5
6
7
8
public void testParams(params int[] arr)
{
Console.Write ("使用Params参数!");
}
public void testParams(int x,int y)
{
Console.Write ("使用两个整型参数!");
}

请问上述方法重载有无二义性?若没有,则下列语句的输出为____。

1
2
3
4
MyClass x = new MyClass();
x.testParams(0);
x.testParams(0,1);
x.testParams(0,1,2);
  • A. 有语义二义性;
  • B. 使用Params 参数!使用两个整型参数!使用Params 参数!
  • C. 使用Params 参数!使用Params 参数!使用Params 参数!
  • D. 使用Params 参数!使用两个整型参数!使用两个整型参数!

答案:B。

解析:执行x.testParams(0,1,2);时,可以认为输入的参数为数组。

题目13ClassA有一个名为M1的方法,在程序中有如下一段代码,假设该段代码是可以执行的,则修饰M1方法时一定使用了____修饰符。

1
2
ClassA obj = new ClassA();
ClassA.M1();
  • A. public
  • B. static
  • C. private
  • D. virtual

答案:B。

解析:要能够执行ClassA.M1();M1方法必须是静态的。

题目14 判断下列类MyClass的定义中哪些是合法的抽象类?

  • A
1
2
3
4
abstract class MyClass 
{
public abstract int getCount();
}
  • B
1
2
3
4
abstract class MyClass 
{
abstract int getCount();
}
  • C
1
2
3
4
private abstract class MyClass 
{
abstract int getCount();
}
  • D
1
2
3
4
sealed abstract class MyClass 
{
abstract int getCount();
}

答案:A。

解析:在抽象类中包含的抽象方法可以是公有或者私有,但是如果是私有的,子类就不能访问,从而没有意义。

控制结构、数组、方法的重载

控制结构

C#的控制结构有if else语句、switch case语句、for循环、while循环等。if语句的用法如下:

1
2
3
4
if(布尔表达式)
{
语句块;
}

另外,if else语句的用法如下:

1
2
3
4
5
6
7
8
9
10
11
if(布尔表达式 1)
{
语句块 1;
}
else if(布尔表达式 2){
语句块 2;
}
...
else{
语句块 n;
}

switch case语句的用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
switch(表达式)
{
case1:
语句块1;
break;
case2:
语句块2;
break;
...
default:
语句块n;
break;
}

for循环的用法如下:

1
2
3
4
for(表达式 1; 表达式 2; 表达式3)
{
表达式 4;
}

其中,表达式1对变量赋初值,表达式2为循环条件,表达式3用于改变变量的大小。while语句的用法如下:

1
2
3
4
while(布尔表达式)
{
语句块;
}

另外,do while语句的用法如下:

1
2
3
4
5
do
{
语句块;
}
while(布尔表达式);

在循环中,可以用breakcontinue

  • break;可以用来终止循环,使循环不再执行;
  • continue;可以用来终止当前循环,进入下一循环。

数组

创建一维数组的方式是:

1
2
3
4
5
6
7
数据类型[] 数组名;

数据类型[] 数组名 = new 数据类型[长度];

数据类型[] 数组名 = {值1, 值2, ...};

数据类型[] 数组名 = new 数据类型[长度]{值1, 值2, ...};

创建多维数组的方式是:

1
2
3
数据类型[ , , ...] 数组名;

数据类型[ , , ...] 数组名 = new 数据类型[m, n, ...] {{ , , ...},{ , , ...},...};

其中每多一个维度就在[]中多一个,。在数组的基础上,可以使用foreach,用法如下:

1
2
3
4
foreach(数据类型 变量名 in 数组名)
{
语句块;
}

一个比较重要的例子是:输入一串数字,用空格隔开,用C#编写时可以使用字符串的Split函数实现。方式如下:

1
2
3
4
5
6
7
var s = Console.ReadLine();
var sSplit = s.Split(' ');
var a = new double[sSplit.Length];
for (var i = 0; i < sSplit.Length; i++)
{
a[i] = Convert.ToDouble(sSplit[i]);
}

这样的结果是,数组a中存储了输入的一串数字。

方法的重载

构成重载的方法具有以下特点:

  • 方法名相同;
  • 方法参数列表不同。

用法如下:

1
2
3
4
5
6
7
8
访问修饰符1 修饰符1 返回值类型1 方法名(参数列表1)
{
语句块1;
}
访问修饰符2 修饰符2 返回值类型2 方法名(参数列表1)
{
语句块2;
}

类的定义、属性、构造方法

类的定义

定义类的方法如下:

1
2
3
4
访问修饰符 修饰符 class 类名
{
成员
}
  • 类的访问修饰符:包括publicinternal
    • internal或不写:只能在当前项目中访问类;
    • public:可以在任何项目中访问类。
  • 修饰符:包括abstractsealedstatic
    • abstract:抽象类,不能被实例化;
    • sealed:密封类,不能被继承;
    • static:静态类,不能被实例化。
  • 类的成员:在类中能定义的元素,主要包括字段、属性、方法。成员的访问修饰符包含publicprivateinternalprotected
    • public:成员可以被任何代码访问;
    • private或不写:成员仅能被同一个类中的代码访问;
    • internal:成员仅能被同一个项目中的代码访问;
    • protected:成员只能由类或派生类中的代码访问。

类的属性

定义属性的方式为:

1
2
3
4
5
6
7
8
9
10
11
12
public 数据类型 属性名
{
get
{
获取属性的语句块;
return 值;
}
set
{
设置属性得到语句块;
}
}

也可以使用自动属性设置:

1
2
3
4
5
public 数据类型 属性名
{
get;
set;
}

类的构造方法

类的构造函数的方法名与类名相同,具体方式为:

1
2
3
4
public 类名(参数列表)
{
语句块;
}

类的继承、多态

类的继承

派生类的声明方式如下:

1
2
3
4
访问修饰符 修饰符 class 派生类 : 基类
{
新增成员
}

在派生类中,可以使用basenew关键字:

  • base可以指代当前类的父类;
  • new可以以”覆盖方式“声明与基类中同名的方法。

另外,派生类的构造方法如下:

1
2
3
4
public 派生类名(参数总表) : base(参数表)
{
语句块;
}

类的多态

在基类中如果有方法需要在派生类中重写,可以使用virtualoverride关键字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
访问修饰符 修饰符 class 基类
{
访问修饰符1 virtual 返回值类型1 方法名(参数列表1)
{
语句块1
}
}
访问修饰符 修饰符 class 派生类 : 基类
{
访问修饰符2 override 返回值类型2 方法名(参数列表2)
{
语句块2
}
}

另外,也可以创建抽象类作为基类,声明抽象方法,并在派生类中重载抽象方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class 抽象类
{
public 返回值类型1 方法名(参数列表1)
{
语句块1
}
}
访问修饰符 修饰符 class 派生类 : 抽象类
{
访问修饰符2 override 返回值类型2 方法名(参数列表2)
{
语句块2
}
}

需要注意的是,在这里抽象类不能实例化。

绘图、文件

绘图

绘图时,首先需要确定点。可以使用Point结构来定义二维平面上的一个点,其中成员X表示X坐标,成员Y表示Y坐标。声明方式为

1
Point 点 = new Point(X坐标, Y坐标);

另外,画图还需要确定画笔,包括其颜色和宽度,声明方式为

1
Pen 画笔 = new Pen(颜色, 宽度);

画笔对应着某个图形的轮廓线的属性,而内部区域的填充一般使用画刷来完成。其声明方式为:

1
SolidBrush 画刷 = new SoildBrush(颜色);

在这里,颜色用Color.指定颜色来表示,比如红色是Color.Red。绘图一般在Form1_Paint事件中完成,并且有多种绘图的方法,例如:

1
2
3
4
5
6
7
8
9
10
11
12
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;

g.DrawLine(点1, 点2); // 绘制直线

g.DrawRectangle(画笔, X坐标, Y坐标, 宽度, 高度); // 画矩形
g.FillRectangle(画刷, X坐标, Y坐标, 宽度, 高度); // 填充矩形

g.DrawEllipse(画笔, X坐标, Y坐标, 宽度, 高度); // 画椭圆
g.FillEllipse(画刷, X坐标, Y坐标, 宽度, 高度); // 填充椭圆
}

文件

为了在程序中打开文件,需要使用OpenFileDialog,例如想要打开.txt文件,并且保存到字符串数组Text中:

1
2
3
4
5
6
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "文本文档(*.txt)|*.txt";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string[] Text = System.IO.File.ReadAllLines(openFileDialog.FileName);
}

其中,Filter表示需要打开的文件的后缀。而如果想要在程序中保存文件,则需要使用SaveFileDialog,例如需要将字符串数组Text保存到.txt文件中:

1
2
3
4
5
6
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "文本文档(*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
System.IO.File.WriteAllLines(saveFileDialog.FileName, Text);
}

课本上读取和写入文件用的是StreamWriter对象和StreamReader对象,上面读取文件的代码可以改写为:

1
2
3
4
5
6
7
8
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "文本文档(*.txt)|*.txt";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
StreamReader streamReader = new StreamReader(openFileDialog.FileName);
Text = streamReader.ReadToEnd();
streamReader.Close();
}

写入文件的代码可以改写为:

1
2
3
4
5
6
7
8
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "文本文档(*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName);
streamWriter.Write(Text);
streamWriter.Close();
}