




已阅读5页,还剩26页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
习题 1 参考解答 1、可以用C#编写哪些类型的应用程序? 【解答】 1)控制台应用程序。 2) Windows应用程序。 3) ASP.NET Web应用程序。 4) ASP.NET Web服务应用程序。 5) ASP.NET 水晶报表Web应用程序。 6)智能设备应用程序。 7)安装和部署应用程序。 2、什么是命名空间?命名空间和类库的关系是什么? 【解答】 1)命名空间是对类的一种逻辑上的分组, 空间下。 2)命名空间又可以包含其它的命名空间,例如System.Windows.Forms,是指System命名空间下有Windows命名空间,Windows命名空间下有Forms命名空间。 3)所有类库都在规定的命名空间下。 3、举例说明using关键字有哪些主要用途。 【解答】 在C#中,using关键字有3个用途 1)指定引用的命名空间,例如:using System.Windows.Forms; 2)简化命名空间的层次表达形式,例如:using WinForm=System.Windows.Form; 3)作为语句,定义一个范围。例如: Font font1 = new Font(Arial, 10.0f); using (font1) 程序执行到“”时,就会自动释放font1对象。 习题 2 参考解答 1、C#支持的数据类型有那些?值类型和引用类型有何不同? 【解答】 C#支持的数据类型有: (1)值类型,包括:简单类型、结构类型、枚举类型。其中,简单类型又分为:整型、布 尔型、字符型、浮点型、小数型。 (2)引用类型,包括:对象类型、类类型、接口、元数据、字符串类型、数组。 值类型和引用类型的区别在于,值类型的变量直接存放实际的数据,而引用类型的变量 存放的则是数据的地址,即对象的引用。当把一个值变量赋给另一个值变量时,会在堆栈 (stack)中保存两个完全相同的值;而把一个引用变量赋给另一个引用变量,则会在堆栈 中保存对同一个堆(heap)位置的两个引用。进行数据操作时,对于值类型,由于每个变 量都有自己的值,因此对一个变量的操作不会影响到其他变量;对于引用类型的变量,对一 个变量的数据进行操作就是对这个变量在堆中的数据进行操作, 用同一个对象, 会影响到引用同一个对象的另一个变量。 2、C#中不同整型之间进行转换的原则是什么? 【解答】 在整型之间进行转换时, 范围类型时需要使用显式转换。 3、简述装箱和拆箱的过程。 【解答】 装箱是将值类型隐式地转换为object类型或者转换为由该值类型实现了的接口类型。装箱 一个数值会为其分配一个对象实例,并把该数值拷贝到新对象中。拆箱是显式地把object类 型转换成值类型,或者把值类型实现了的接口类型转换成该值类型。 4、分别写出下列语句执行的结果。 1) Console.WriteLine(0-0:pgood,12.34F); 2) Console.WriteLine(0-0:#good,0); 3) Console.WriteLine(0-0:00000good,456); 【解答】 12.34-1,234.00%good 0-good 456-00456good 5、编写一个控制台应用程序,输出1到5的平方值,要求: 1) 用for语句实现。 2) 用while语句实现。 3) 用do-while语句实现。 【解答】 using System; using System.Collections.Generic; using System.Text; namespace outputSquareValue class Program static void Main() /用for语句实现 for (int i = 1; i = 5; i+) Console.WriteLine(0的平方值为1, i, i * i); /用while语句实现 int j = 0; while (j+ 5) Console.WriteLine(0的平方值为1, j, j * j); /用do-while语句实现 int k = 1; do Console.WriteLine(0的平方值为1, k, k * k); while (k+ 5); Console.ReadLine(); 6、编写一个控制台应用程序,要求用户输入5个大写字母,如果用户输入的信息不满 足要求,提示帮助信息并要求重新输入。 【解答】 using System; using System.Collections.Generic; using System.Text; namespace inputCapitalLetter class Program static void Main() bool ok = false; while (ok = false) Console.Write(请输入5个大写字母:); string str = Console.ReadLine(); if (str.Length != 5) Console.WriteLine(你输入的字符个数不是5个,请重新输入。); else ok = true; for (int i = 0; i 5; i+) char c = stri; if (c Z) Console.WriteLine(第0个字符“1”不是大写字母,请重新 输入。, i + 1, c); ok = false; break; 7、编写一个控制台应用程序,要求完成下列功能。 1) 接收一个整数n。 2) 如果接收的值n为正数,输出1到n间的全部整数。 3) 如果接收的值为负值,用break或者return退出程序。 4) 转到(1)继续接收下一个整数。 【解答】 using System; using System.Collections.Generic; using System.Text; namespace testOutput class Program static void Main() while (true) Console.Write(请输入一个整数(负值结束):); string str = Console.ReadLine(); try int i = Int32.Parse(str); if (i 0) break; for (int j = 1; j = i; j+) Console.WriteLine(j); catch Console.WriteLine(你输入的不是数字或超出整数的表示范围, ); 8、编写一个控制台应用程序,求1000之内的所有“完数” 等于它的所有因子之和。例如,6是完数,因为6=1+2+3。 【解答】 using System; using System.Collections.Generic; using System.Text; namespace completeNumber class Program static void Main(string args) for (int i = 2; i = 1000; i+) int s = 1; string str = 1; for (int j = 2; j = (int)Math.Sqrt(i); j+) if (j * (i / j) = i) if (j != i / j) s += j + i / j; str += string.Format(+0+1, j, i / j); else s += j; str += string.Format(+0, j); if (s = i) Console.WriteLine(0=1, i, str); Console.ReadLine(); 9、错误和异常有什么区别,为什么要进行异常处理,用于异常处理的语句有哪些? 【解答】 错误是指在执行代码过程中发生的事件, 当错误中断流程时, 代码) 当使用短语“产生异常”时,表示存在问题的方法发生错误,并创建异常对象(包含该 错误的信息及发生的时间和位置) 错误、资源失败和编程逻辑失败。这些错误与代码实现特定任务的方法有关,而与该任务的 目的无关。 如果不进行异常处理,即不对错误做出响应,程序的健壮性就会大打折扣,甚至无法保 证正常运行,所以必须要进行异常处理。 用于异常处理的语句有:try-catch语句、try-catch-finally语句、throw语句。 习题 3 参考解答 1、C#语言中的数组类型有何特点? 【解答】 1)数组一般用于存储同一种类型的数据,包括Object类型。 2)数组是一种引用类型,而不是值类型。 3)C#中除了可以有一维数组、多维数组外,还有交错型数组。 2、泛型和非泛型的主要区别是什么?为什么说使用泛型比使用对应的非泛型效率高? 【解答】泛型是数据类型的一种通用表示形式,它可以表示任何一种数据类型。泛型 (Generic)是具有占位符(类型参数)的类、结构、接口和方法,它与普通类的区别是泛 型多了一个或多个表示类型的占位符,这些占位符用尖括号括起来。占位符表示某种类型, 这种类型在创建泛型类的实例时才用实际类型来替换。定义一个类或者方法时,可以用泛 型占位符代表任何一种类型,而在引用时再指定具体类型。当代码调用泛型类或方法时,C#编译器会自动将定义的泛型转换为引用代码中指定的类型,从而大大简化了程序员编 写代码的复杂度。另外,由于占位符可以代表任何一种类型,因此在方法中只定义一次类 型就能实现所有类型的引用。 3、编写一个控制台应用程序,计算 x 2 x 3 x 4 + L + ( 1) ( n + 1) 1 + x + 2! 3! 4! 要求精度为108。 【解答】 using System; class Test3 public static void Main() int n = 50; double x = 3; double s = 0; double a = 1; for (int i = 1; i = n; i+) a *= i; s += Math.Pow(-1, i + 1) * Math.Pow(x, i) / a; Console.WriteLine(n=0,s=1:0.00000000, n, s); x n n!4、编写一个控制台应用程序,接收一个长度大于3的字符串,完成下列功能。 (1)输出字符串的长度。 (2)输出字符串中第一个出现字母a的位置。 (3)在字符串的第3个字符后面插入子串“hello” (4)将字符串“hello”替换为“me” (5)以字符“m”为分隔符,将字符串分离,并输出分离后的字符串。 【解答】 【解答】 using System; class Test4 public static void Main() string str = ; while (str.Length -1) Console.WriteLine(第一个出现字母a的位置是:0, i); else Console.WriteLine(字符串中不包含字母a。); /(3) string str1 = str.Insert(3, hello); /在第3个(初始序号为)字符前插入hello Console.WriteLine(插入hello后的结果为:0, str1); /(4) string str2 = str1.Replace(hello, me); Console.WriteLine(将hello替换为me后的结果为:0, str2); /(5) string arr = str2.Split(m); Console.WriteLine(以m为分隔符分离后的字符串有:); for (int j = 0; j arr.Length; j+) Console.WriteLine(arrj); 习题 4 参考解答 1、编写一个控制台应用程序,完成下列功能。 (1)创建一个类,用无参数的构造函数输出该类的类名。 (2)增加一个重载的构造函数,带有一个string类型的参数,在此构造函数中将传递的字 符串打印出来。 (3)在Main方法中创建属于这个类的一个对象,不传递参数。 (4)在Main方法中创建属于这个类的另一个对象,传递一个字符串“This is a string.” (5)在Main方法中声明类型为这个类的一个具有5个对象的数组,但不要实际创建分配 到数组里的对象。 (6)写出运行程序应该输出的结果。 【解答】 using System; class Test1 public Test1() Console.WriteLine(this); public Test1(string str) Console.WriteLine(str); public static void Main() Test1 t1 = new Test1(); Test1 t2 = new Test1(This is a string.); Test1 t3 = new Test15; 输出结果: Test1 This is a string. 2、编写一个控制台应用程序,定义一个类MyClass,类中包含有public、private以及protected数据成员及方法。然后定义一个从MyClass类继承的类MyMain,将Main方法 放在MyMain中, Main方法中创建MyClass类的一个对象, 及方法。要求注明在试图访问所有类成员时哪些语句会产生编译错误。 【解答】 using System; class MyClass public int i; private int j; protected int k; public void method1() Console.WriteLine(public method.); private void method2() Console.WriteLine(private method.); protected void method3() Console.WriteLine(protected method.); class MyMain : MyClass public static void Main() MyClass t = new MyClass(); Console.WriteLine(i=0, t.i); /会出现编译错误,私有成员不允许在其它类中访问 Console.WriteLine(k=0, t.k); /会出现编译错误,应该创建MyMain的对象,然 /后通过MyMain的对象访问 t.method1(); /会出现编译错误,私有的方法不允许在其它类中调用 /会出现编译错误,应该创建MyMain的对象,然后通过MyMain的 /对象调用该方法 3、创建一个类包含有protected数据。在相同的文件里创建第二个类,用一个方法操纵第 一个类里的protected数据。 【解答】 using System; class Class1 protected int i = 5; protected void MyMethod() Console.WriteLine(protected method.); class Class2 : Class1 private void NewMethod() Console.WriteLine(this.i); this.i += 10; Console.WriteLine(this.i); public static void Main() Class2 t = new Class2(); t.NewMethod(); 4、结构和类的区别是什么? 【解答】 1)结构是一个值类型,保存在栈上,而类是一个引用类型,保存在受管制的堆上。 2)对结构中的数据进行操作比对类或对象中的数据进行操作速度要快。 3)一般用结构存储多种类型的数据,当创建一个很多类或对象共用的小型对象时,使用结 构效率更高。 习题 5 参考解答 1、简要回答下列问题。 (1)举例说明new关键字可用于哪些方面? (2)sealed关键字的作用是什么?什么情况下需要使用sealed关键字? (3)哪些关键字可以用于版本控制? 【解答】 1)在C#中,new关键字可用作运算符或修饰符。作为运算符用于在堆上创建对象和调用构 造函数。作为修饰符用于隐藏基类成员的继承成员。 2) 在类声明中使用sealed修饰符可防止其它类继承此类。在方法声明中使用sealed修饰 符可防止扩充类重写此方法。 sealed修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。具体说来, 由于密封类永远不会有任何派生类, 非虚拟调用来处理。 3) override关键字和new关键字均可用于版本控制。 在C#中,默认情况下方法不是虚拟的。若要使方法成为虚拟方法,必须在基类的方法声 明中使用virtual修饰符。然后,派生类可以使用override关键字重写基类中的虚拟方法, 或使用new关键字隐藏基类中的虚拟方法。如果override关键字和new关键字均未指定, 编译器将发出警告,并且派生类中的方法将隐藏基类中的方法。 2、简要回答抽象类和接口的主要区别。 【解答】 抽象类和接口的一个主要差别是:类可以实现多个接口,但仅能从一个抽象类或任何其 它类型的类继承。 3、编写一个控制台应用程序,完成下列功能,并回答提出的问题。 (1)创建一个类A,在构造函数中输出“A” (2)从A继承一个名为C的新类,并在C内创建一个成员B。不要为C创建构造函数。 (3)在Main方法中创建类C的一个对象,写出运行程序后输出的结果。 (4)如果在C中也创建一个构造函数输出“C” 【解答】 using System; public class A public A() Console.WriteLine(A); public class B public B() Console.WriteLine(B); public class C : A B newb = new B(); class MainClass public static void Main() C newc = new C(); Console.ReadLine(); 输出结果: B A 如果在C中也创建一个构造函数输出“C” public C() Console.WriteLine(C); 则整个程序运行的结果为: B A C 4、编写一个控制台应用程序,完成下列功能,并写出运行程序后输出的结果。 (1)创建一个类A,在A中编写一个可以被重写的带int类型参数的方法MyMethod,并 在该方法中输出传递的整型值加10后的结果。 (2)再创建一个类B,使其继承自类A,然后重写A中的MyMethod方法,将A中接收的 整型值加50,并输出结果。 (3)在Main方法中分别创建类A和类B的对象,并分别调用MyMethod方法。 【解答】 using System; public class A public virtual void MyMethod(int num) num += 10; Console.WriteLine(num); public class B : A public override void MyMethod(int num) num += 50; Console.WriteLine(num); class MainClass public static void Main() A newa = new A(); newa.MyMethod(2); B newb = new B(); newb.MyMethod(2); Console.ReadLine(); 输出结果: 12 52 5、假设Node类的每一个节点包括有两个字段:m_data(引用节点的数据)和m_next(引 用链接列表中的下一项) 个功能是通过名为Data和Next的只读属性访问m_data和m_next字段。 System.Object的ToString虚拟方法进行重写。 述功能。 【解答】 using System; class Node Object m_data; Node m_next; public Node(Object data, Node next) m_data = data; m_next = next; / 访问结点数据 public Object Data get return m_data; / 访问下一个结点 public Node Next get return m_next; / 获取结点数据描述 public override String ToString() return m_data.ToString(); / 链表结点类的泛型定义 class Node T m_data; Node m_next; public Node(T data, Node next) m_data = data; m_next = next; / 访问结点数据 public T Data get return m_data; set m_data = value; / 访问下一个结点 public Node Next get return m_next; set m_next = value; / 获取结点数据描述 public override String ToString() return m_data.ToString(); / 使用结点类型或泛型结点类型 class LinkedList static void Main(string args) / 创建整数链表 /Node head = new Node(5, null); /head = new Node(10, head); /head = new Node(15, head); /遍历链表求整数和 /Int32 sum = 0; /for (Node current = head; current != null; / / / / current = current.Next) sum += (Int32)current.Data; / 输出结果 /Console.WriteLine(Sum of nodes = 0, sum); / 用泛型创建整数链表 Node head = new Node(5, null); head = new Node(10, head); head = new Node(15, head); / 遍历求和 Int32 sum = 0; for (Node current = head; current != null; current = current.Next) sum += current.Data; / 输出 Console.WriteLine(Sum of nodes = 0, sum.ToString(); 习题 6 参考解答 1、填空题 (1)使控件是否可以对用户交互做出响应的属性是(Enabled) (2)控制控件是否显示的属性是(Visible) (3)若要在文本框中输入密码,常指定(PasswordChar)属性。 (4)若某复选框某时刻【CheckState】属性的值为Indeterminate,则其属性【Checked】的值 为(true) (5)使用(GroupBox)或(Panel)控件可以将多个RadioButton控件分为两个单选组。 (6)若不希望用户在ComboBox控件中编辑文本,则应将属性(DropDownStyle)的属性值 设置为DropDownList。 2、简要介绍TextBox控件、MaskedTextBox控件和RichTextBox控件的使用场合。 【解答】 TextBox控件一般用于单段文本的编辑,可以设置为单行或多行的输入模式,也可以用 作密码的输入;MaskedTextBox控件主要用于特定格式的单段文本编辑,在输入文本不符合 格式要求的将会触发其MaskInputRejected事件;文本编辑功能外,还可以进行多段文本的高级编辑功能,如改变文本、段落的显示格式、在 文本中查找特定字符和字符串以及与Rtf文件的交互等。 3、简要说明CheckBox控件和RadioButton控件的区别。 【解答】 CheckBox控件可为用户提供选择功能,常用的是二选一的选择,如“真/假”或“是/否” 是独立的,若有多个CheckBox控件构成一组选项时,则可以多个同时被选中,相互之间不 影响,即复选。RadioButton控件,它与CheckBox控件功能类似,也是用于接收用户的选 择,但它是以单项选择的形式出现,即一组RadioButton按钮中只能有一个处于选中状态。 一旦某一项被选中,则同组中其他RadioButton按钮的选中状态自动清除。 4、设计一个Windows应用程序,窗体上有一个TextBox控件、一个Button控件。要求: 每当用户单击按钮时,文本框都会增加一行文字来反映单击的次数,例如, 按钮” 【解答】 1) 窗体界面如图6-1所示; 2) 窗体中主要控件属性设置如表6-1; 表6-1 窗体中的主要控件属性 控件 TextBox控件 Button控 件 Name属性 textBox1 Button1 Button2 功能 显示信息 触发添加信息事 件 触发结束添加事 件 其它属性 ScrollBars=Vertical; Multiline=True 3) 主要事件代码。 int i = 1; bool Add = true; private void button1_Click(object sender, EventArgs e) if(Add) textBox1.Text += 第 + i + 次单击按钮; i+; private void button2_Click(object sender, EventArgs e) Add = false; 5、编写一段程序,向名为listBox1的ListBox控件中,自动添加10个随机数,每个数占一 项。 【解答】 主要代码如下。 public partial class Form1 : Form int m = 1; private void button1_Click(object sender, EventArgs e) for (int i = m ; i m+10; i+) listBox1.Items.Add(i); m = m + 10; 习题 7 参考解答 1、Directory类提供了哪些目录管理的功能,它们是通过哪些方法来实现的? 【解答】 Directory类为我们提供了对磁盘和目录进行管理的功能,如复制、移动、重命名、创 建和删除目录,获取和设置与目录的创建、访问及写入操作相关的时间信息。 如:CreateDirectory方法用于创建指定路径中的所有目录;Delete方法用于删除指定的 目录;Move方法能够重命名或移动目录;Exists方法用于确定给定路径是否引用磁盘上的 现有目录;GetCurrentDirectory方法用于获取应用程序的当前工作目录;GetFiles方法用于 返回指定目录中的文件的名称等。 2、编写程序用Directory类提供的方法确定指定的目录是否存在,如果不存在,则创建该目 录。然后在其中创建一个文件,并将一个字符串写到文件中。 【解答】 程序清单如下: using System; using System.IO; class Test public static void Main() string path = c:; try if (!Directory.Exists(path) Directory.CreateDirectory(path); StreamWriter sw=File.CreateText(path+.txt); sw.WriteLine(This is a String!); sw.close(); catch (Exception e) Console.WriteLine(操作失败: 0, e.ToString(); finally 3、编写程序,使用File类实现删除指定目录下的指定文件。 【解答】 程序清单如下: using System; using System.IO; class FileTest public static void Main() Console.WriteLine(确认删除当前目录下的所有文件?); Console.WriteLine(点击Y键继续,其它键取消操作); int a = Console.Read(); if(a = Y | a = y) Console.WriteLine(正在删除文件.); else Console.WriteLine(用户取消操作); return; DirectoryInfo dir = new DirectoryInfo (.); foreach (FileInfo f in dir.GetFiles() f.Delete(); 习题 8 参考解答 1、简述有哪些创建Graphics类对象的方法。 【解答】 (1)在窗体或控件的Paint事件中直接引用Graphics对象。在为窗体创建绘制代码时,一般使 用此方法获取对图像的引用。 (2)从当前窗体获取对Graphics对象的引用。注意这种对象只有在处理当前Windows窗体消 息的过程中有效。如果想在已经存在的窗体或控件中绘图,可以使用此种方法。 (3)从继承自图像的任何对象创建Graphics对象。 2、使用Panel控件分别以矩形、椭圆和圆形的方式动态显示图片,图片的大小由Panel控件 的大小决定。 【解答】 (1)新建一个Windows应用程序,命名为“ShowImageExe”,调整窗体到适当大小。更 改“Form1.cs”为“FromShowImageExe.cs” (2)切换到代码方式,添加名称空间引用: using System.Drawing.Drawing2D; (3)添 加 四 个Button控 件 分 别 命 名 为 “buttonOpenFile” “buttonRectangle” “buttonEllipse” “buttonRound” (4)在Form类下声明两个私有变量filename和flag,分别用来记录打开的文件名和判断 哪个按钮的click时间被触发。 private string filename = ; private int flag = 0; (5) 添加【打开文件】按钮的click事件 private void buttonOpenFile_Click(object sender, EventArgs e) openFileDialog1.ShowDialog(); filename = openFileDialog1.FileName; panel1.Refresh(); (6) 在panel1控件的paint事件下添加如下代码: private void panel1_Paint(object sender, PaintEventArgs e) if (filename.Trim() = ) return; Bitmap mybitmap = new Bitmap(filename); Graphics g = e.Graphics; TextureBrush mybrush = new TextureBrush(mybitmap,WrapMode.Clamp); /保证图片完全由绘制对象的边框决定 switch (flag) case 1: g.FillRectangle(mybrush, panel1.ClientRectangle); break; case 2: g.FillEllipse(mybrush, panel1.ClientRectangle); break; case 3: g.FillEllipse(mybrush,(panel1.Width-panel1.Height)/2,0, panel1.Height,panel1.Height); break; (7) 在其他几个按钮的click事件中分别添加如下代码: private void buttonRectangle_Click(object sender, EventArgs e) flag = 1; panel1.Refresh(); private void buttonEllipse_Click(object sender, EventArgs e) flag = 2; panel1.Refres
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 光大银行晋城市城区2025秋招笔试英语题专练及答案
- 华夏银行成都市金牛区2025秋招结构化面试经典题及参考答案
- 社区基础考试试题及答案
- 招商银行连云港市连云区2025秋招笔试热点题型专练及答案
- 贵州省2025年医师资格考试医学综合考试“年两试”口腔执业医师复习题库及答案
- 兴业银行福州市台江区2025秋招笔试价值观测评题专练及答案
- 《药物化学》考试复习题库及答案
- 中信银行岳阳市岳阳楼区2025秋招面试典型题目及参考答案
- 农发行昆明市官渡区2025秋招半结构化面试题库及参考答案
- 套筒卷制工新员工考核试卷及答案
- 辽宁省大连市甘井子区2024-2025学年上学期七年级 月考英语试卷(10月份)
- 地质灾害防治工程勘察规范DB50143-2003
- 介绍费合同书范本
- 中考英语高频词汇大纲表(人教版)
- 共享办公室租赁合同
- 血透患者跌倒的预防及管理
- NBT 31066-2015 风电机组电气仿真模型建模导则
- 《儿童铁缺乏和缺铁性贫血防治专家共识2023》解读
- 中国子宫内膜增生管理指南(2022)解读
- 2007-2000央美考研题库
- TB 10012-2019 铁路工程地质勘察规范
评论
0/150
提交评论