• C#学习笔记(二十):C#总结和月考讲解


    m1w1d2_console_variable_constant

    输入Console.WriteLine();
    输出Console.ReadLine();
    
    快捷键
    折叠代码:快捷键“Ctrl+ K + S”
    隐藏当前代码:组合键“Ctrl + M,M”
    显示全部代码:组合键“Ctrl + M,L”
    注释:组合键“Ctrl + K + C”;
    取消注释:组合键“Ctrl + K + U”
    批量操作:按住Alt选择一片区域,前段会有蓝线
    
    快捷写法
    Console.WriteLine();CW + 双击T
    switch语句快速生成枚举方法,复制枚举名在switch()里,双击TAB
    for循环,按两下TAB
    i++:for+按两下TAB
    i--:forr+按两下TAB
    
    变量名命名要求
    1、变量名头必需以字母或下划线"_"开头
    2、变量名体只能是数字,字母,下划线的组合
    3、不能使用编程语言的关键字
    4、在作用域内,不能同名
    
    命名是有法则的
    1、命名要有意义(概括变量里数据的规律)
    2、变量使用驼峰命名法(除了第一个单词首字母小写,其余单词首字母全大写)
    3、类与方法使用帕斯卡命名法(每个单词的首字母都大写)
    
    1、定义一个变量:数据类型 变量名;
    2、给变量赋值:变量名 =(赋值符号) 值(数据)
    
    常量:
    const 数据类型 常量名
    命名法则:全大写,单词之间用下划线分隔
    常量在定义时一定要赋值(初始化赋值)
    常量的值不可以更改

    m1w1d2_ide

    关闭番茄插件的拼写纠错,Visual Assist Options的Underlining
    调整行号:工具-选项-文本编辑器-C#-行号
    调整主题:工具-选项-环境-常规-颜色主题-深色
    调整字体:工具-选项-环境-字体颜色(推荐字体Consolas)
    
    取数据类型的长度:sizeof()
    基础数据类型所占字节:
    
    ASCII表
    0-948-57
    A-Z:65-90
    a-z:97-122
    
    字符串格式化输出:
    Console.Writeline($"最大值{max}");
    $符号,{}里可以直接填变量
    
    显式转换:
    Convert:用于所有基本类型之间的转换
    Convert.ToInt16('A');
    
    Parse:将字符串转换成一个特定类型
    int.Parse(Console.ReadLine());
    
    强制转换符:用于数值类型(整型,浮点型,char)和派生(继承)之间的转换
    int a = (int)'a'

    m1w1d4_operator

    条件运算符:第一表达式?第二表达式:第三表达式
    第一表达式必须是布尔表达式
    第二和第三表达式必须和接收的类型一致
    如果第一表达式为true时,返回第二表达式结果
    如果第一表达式为false时,返回第三表达式结果

    m1w1d5_randomnumber

    随机数
    Random roll = new Random();
    roll.Next(-10 , 11);

    m1w2d2_complex_datatype

    基本数据类型
    1、定义变量,2、使用变量
    复杂数据类型
    1,定义类型,2、定义这个类型的变量、2、使用变量
    
    枚举:一般情况我们用枚举来表示一组状态的集合
    定义类型 一般情况下我们都放在类外面定义
    enum 自定义枚举名
    {
    成员(枚举项),
    成员(枚举项),
    }
    每个枚举项都可以赋整数值
    如果没有赋值,他的值是前一枚举项的值+1
    第一个枚举项如果不赋值,默认值0
    赋值原因:给枚举项建立数学联系(属性相克)
    定义这个类型的变量时,枚举的值,只能是所规定的枚举项
    自定义枚举名 变量名 = 自定义枚举名.某一枚举项
    
    枚举转字符串:对应的变量,调用toString()方法,可以将枚举转字符串
    字符串转成枚举:(Occupation)Enum.Parse(typeof(Occupation), "道士");

    m1w2d3_array

    1、定义一个数组变量
    数据类型[] 变量名;
    int[] array;
    数据类型[] 变量名 = {成员,成员};
    int[] array1 = { 1, 2, 3, 4, 5 };//不指定元素个数,只指定元素
    int[] array2 = new int[8] { 1, 2, 3, 4, 5, 6, 7, 8 };//先限制元素个数,然后再指定元素
    数据类型[] 变量名 = 指定的长度空数组。
    int[] array3 = new int[8];//最常用的形式,不关心值,只关心处理逻辑
    元素的值是默认值(微软MSDN默认值)
    数值类型是对应0
    如果字符串是" "
    
    2、使用数组
    访问成员,通过下标 变量名[下标号]访问对应下标的成员
    array1[2] = 100;
    Console.WriteLine(array1[2]);
    如果我使用的下标是负数,或者超出了元素个数,指定了数组中一个不存在的元素
    会出现 越界异常
    下标的有效范围是(0 - 数组名.Length-1)
    Console.WriteLine(array1.Length);
    Console.WriteLine(array1.[array1.Length - 1 ]);
    通过数组名.Length我们能知道这个数组中有多少个元素
    
    3、遍历数组
    遍历就是从一个 数据结构 第一个元素 到 最后一个元素
    遍历就是把 数据结构中 所有元素访问完
    
    Length:取数组元素的总个数
    GetLength:取不同维度的个数

    m1w2d3_struct_array

    结构体
    用途:一般情况下我们使用结构体来描述复杂事物,如桌子,如位置
    这个复杂事物不能包含自己,会发生递归调用
    结构体用于:属性不多,频繁计算的复杂事物
    结构体储存在栈里,运行速度快,但栈里的空间宝贵,所以用来描述的事物不宜过多(<=5)(也可以不放在栈里,运算不用跳地址)
    一般用于定义常用的数学概念及其需要计算的结果
    
    定义结构体的类型
    struct 自定义类型名{成员;成员;}
    成员之间用分号隔开
    成员是其它数据类型
    成员需要外部访问要用public
    
    定义结构体的变量
    数据类型 变量名 = 初始值;
    Student xiaoMing = new Student();//一次性给结构体里所有变量附初值
    
    
    数组 冒泡排序
    //1、先写内循环,循环次数为:数组长度-1-外循环当前次数
    //2、内循环每次对比当前位置与下一位置,如果逻辑(当前位大于对比位)达成 则交换位置
    //3、外循环,循环次数为 数组长度-1
    for (int i = 0; i < array.Length - 1; i++)
    {
    for (int j = 0; j < array.Length - 1 - i; j++)
    {
    if (array[j] > array[j + 1])
    {
    int temp = array[j];
    array[j] = array[j + 1];
    array[j + 1] = temp;
    }
    }
    }
    
    二维数组也是解决重复数据的重复逻辑,不同的是他允许我们通过两(多)个下标
    为什么用多个下标,人们在生活,经常需要处理二维的数据,地图,表单(纯三维数据特别的少)
    本质上,内存中一维和二维数组是一样的
    
    使用二维数组
    定义二维数组
    不指定元素
    数据类型[,] 变量名;
    指定元素
    数据类型[,] 变量名 = new 数据类型[标号为0维度的元素个数,标号为1维度的元素个数]
    数据类型[,] 变量名 = new 数据类型[行数,列数]
    数据类型[,] 变量名 = new 数据类型[x,y]
    
    交错数组与多维数组的区别
    交错数组理论上才是数组的数组
    1、多维数组必须是每一个维度的元素个数相等,多维数组只能表示矩形数据块
    交错数组可以表示锯齿数据块
    2、多维数组必须是指定每一个维度的元素个数
    交错数组只能指定最外层的数组个数
    3、多维本质上是一块连续内存空间,为什么是多维表示,为了人们方便去理解,多维和一维只是索引器不一样
    交错数组理论上才是数组的数组
    
    定义一个交错数组
    数据类型[][]变量名;
    数据类型[][]变量名 = new 数据类型[4][]{new int[10],new int[5],new int[10],new int[5],}
    数据类型[][]变量名 = new 数据类型[4][];

    m1w2d6_debug

    string.IsNullOrEmpty(s);//判断字符串是否为空
    
    String.Split
    
    1、用字符串分隔:
    string str1 = "aaajsbbbjsccc";
    string[] sArray1 = Regex.Split(str1, "js", RegexOptions.IgnoreCase);
    foreach (string i in sArray1) Console.Write(i.ToString() + "
    ");
    Console.WriteLine("
    ");
    
    2、用单个字符来分隔:
    string str3 = "aaajbbbjccc";
    string[] sArray3 = str3.Split('j');
    foreach (string i in sArray3) Console.Write(i.ToString() + "
    ");
    Console.WriteLine("
    ");
    
    3、用多个字符来分隔:
    string str2 = "aaajbbbscccjdddseee";
    string[] sArray2 = str2.Split(new char[2] { 'j', 's' });
    foreach (string i in sArray2) Console.Write(i.ToString() + "
    ");
    Console.WriteLine("
    ");
    
    SubString 方法:
    string str = "abcdefgh";
    Response.Write(str.Substring(0, 1));//return:a
    Response.Write(str.Substring(2, 3));//return:cde
    Response.Write(str.Substring(7, 1));//return:h
    Response.Write(str.Substring(7));//return:h
    Response.Write(str.Substring(10));//error:startIndex 不能大于字符串长度。
    Response.Write(str.Substring(7, 10));//error:索引和长度必须引用该字符串内的位置。

    m1w2d6_function_flyingchess

    函数是对逻辑(语句序列)的封装,方便以后重复使用
    函数的签名{函数体}
    指令逻辑(什么指令) 对谁(参数) 做什么(函数体) 结果如何(返回类型)
    参数 可以是任意类型
    函数体 可以是任意语句
    返回类型 可以是任意类型 void(无返回类型)
    如果指定了返回类型 必须有相应的返回值
    使用return可以返回一个值,并结束函数
    如果你使用了void,也可以使用return,这时,他不再返回值,但结束函数
     
    返回类型 函数名 (参数列表)
    {
    函数体
    }

    m1w3d1_function_parm_overload_oop

    ref关键字
    在定义方法时 使用 参数修饰 ref 我们可以传递一个地址
    1,定义方法参数使用ref关键字,调用时同时也可使用
    2,调用时,实际参数必须有被赋值
    
    函数的重载
    函数允许我们重名,重名函数在重载的情况下是允许的
    参数列表不一样时构成重载
    重载函数有助我们统一理解
    1、参数个数不一样
    2、类型和顺序不一样
    
    递归的调用
    函数递归 指 函数自身 调用自身的 一种算法
    在算法没有写错的情况 所以他有可能会造成 堆栈溢出异常
    一般用递归解决子问题就是父问题的问题
    
    边界 在递归过程中,我们必须得有一种已知情况
    边界参数要交给自己
    边界参数要无尽的趋向边界
    
    值类型与引用类型的存储方式:
    引用类型:引用类型存储在堆中。类型实例化的时候,会在堆中开辟一部分空间存储类的实
    例。类对象的引用还是存储在栈中。
    值类型:值类型总是分配在它声明的地方,做为局部变量时,存储在栈上;类对象的字段时,
    则跟随此类存储在堆中。

    m1w3d2_class_oop

    类的定义
    程序中的类,是属性和方法的封装
    定义的格式和结构一样,只是关键字不一样用class
    成员不一样,类允许使用任意类型的成员
    
    类到对象
    通过实例化,我们可以将类实例化成某一个具体的对象
    通过 new 关键字 结合构造函数 可以实例化 一个具体的对象
    通过初始化,可以确保这个对象有自己专有的值
    数据类型 变量名 = 初始化值;
    
    对象
    对象是类的一个实例
    我们用this关键指向自己这个对象
    某一个类的对象拥有这个类所有的属性和方法,换言之,一个类的对象和这个类的属性和方法是一致的
    同一个类的对象一般表现为数据不同,而属性和方法是一致的
    
    构造 - 被使用 - 析构
    构造
    实例化可以将一个类实例化成一个对象
    Student xiaoMing = new Student();
    实例化会在内存中开辟一块空间,然后初始化(对空间中的成员添值,添值的逻辑我们交给构造函数)
    
    构造函数
    构造函数只能写在本类里
    和函数大体一致
    1、没有返回类型
    2、函数名和类名一致
    构造函数允许我们重载
    当你不写构造函数时,会有一个默认构造存在
    一旦重载,默认构造就会消失
    一般情况下,我们会保留默认构造,再写一个默认构造(无参构造)
    通过重载构造 我们可以对对象赋予不同的数据
    通过this关键字,我们可以用一个构造函数 调用 另一个构造
    一般情况下有多个构造 我们就用直接指向参数最多的构造
    Student():this("小明"18"")
    
    结构体与类的区别
    1、结构体对象属于值类型,类对象属于引用类型
    2、结构体中的字段不能赋初值 类中可以
    3、结构体中不能显式定义无参构造函数,如果是重写了带参的构造函数,那么就需要对所有字段初始化
    4、结构体放在栈里里,读写速度快,类放在堆里
    
    类一般定义在命名空间下面
    一种模板 这个模板就是用来创建对象的 通过这个模板可以创建对象的属性和方法
    m1w3d3_attribute_inherit_visit
    属性
    1、和方法大体一样,返回类型不能是void,没有参数列表
    如果你保护哪个字段,建议属性名用字段的帕斯卡命名法
    
    2、属性块中由两个块组成get,set
    get块在被使用(取值)时是被调用
    set块在赋值时才会被调用
    set get块可以由空语句替代
    必须全部由空语句替代,或者没有set
    get块和set块可以只有一个
    
    3、get块必须有返回值,值类型与属性返回类型一致
    
    4、在对应字段写入相应逻辑
    属性的简写
    get set块 可以是空语句,set块可以没有
    这样的属性我们叫做自动属性,自动属性可以帮助我们快速实现一个自动属性
    自动属性有保护的字段

    m1w3d4_inherit

    继承
    如果我们定义了若干类,这些类都有一些共有的属性和方法
    我们可以把这些共有部分抽象建立一个新的类,作为基类
    已解决我们代码重复的问题,以便于管理
    如果继承关系建立,子类的构造函数将会默认指向父类的无参构造
    我们可以通过this调用自身的另一个构造函数
    我们可以通过base调用父级的构造函数
    继承:子类继承的是父类所有成员
    但是你只能访问父类成员作用域允许的成员,除了private
    如果你的成员需要外部访问,只能是public
    
    里氏转换
    1、子类(Reporter)可以当父类(Person)用
    一个对象的实际类型是指他被构造出来时的类型
    2、如果父类中的实际对象是子类,我们可以将其转成子类
    is关键字 可以帮助我们判定一个对象中是否包含另一个对象类型
    对象 is 包含的类型
    as关键字 尝试性转换,如果转换成功则返回对应类,不成功则返回null
    对象 as 尝试转换的类型

    m1w3d5_virtual

    多态 用虚方法实现
    多态实现 真的鸭子嘎嘎叫,木头鸭子吱吱叫,橡皮鸭子唧唧叫
    多态 不同的实际对象,在同一个指令(叫),有不同的表现
    不同的对象,如何统一管理 里氏转换:可以把子级当父级 如果这些不同的对象全继承自一个父类
    统一管理 如果把子级转换成了父级,子级的特性丢失了
    
    用虚方法可以 用父级管理并且保留子级的特性 已解决问题
    1,在实例方法前加 virtual
    2,在派生类中用 override 重写 同名/同签名的方法
    在一个虚方法被调用时,会根据最后重写的那个方法和实际类型来决定
    不会根据当前类型来执行方法

    m1w4d1_abstract

    抽象函数、抽象类
    多态实现 写一个动物的 抽象类,写两个子类狗狗叫,猫猫叫
    
    Animal类Cry方法里写具体实现的问题:写什么都不合适
    实例化 一个 animal的对象 他指代现实中 哪种对象 无法解释
    如果有以上情况,我们可以用抽象函数,以便管理,以提高代码可读性
    
    抽象函数
    抽象函数用abstract关键字修饰
    抽象函数只能存在于抽象类中
    抽象函数不允许你实现,不需要写函数体,用空语句代替
    
    抽象类
    一个用abstract关键字修饰过的类,我们叫抽象类
    抽象类中可以有抽象成员,也可以有普通成员
    继承了抽象类的派生类,必须实现抽象类所有的抽象成员
    抽象类不允许我们实例化,但是有构造函数并且可以重载
    
    所以我们在写一个程序结构或者框架的时候会用到抽象类
    m1w4d1_interface
    不同对象 可以使用同一方法 表现不同行为
    这些对象要同一个结构(数组)里 管理结构(容器)
    
    如果多个接口出现了同名的成员,在实现的时候,默认是共用的
    如果你想区分不同接口的不同方法,我们可以使用接口的显示实现
    接口名.成员名
    显示实现的成员必须由接口类型调用
    
    1,多继承
    2,多态
    
    和类大体一致,关键字interface
    成员没有实现,函数是没有函数体,用空语句,属相必须是自动属性
    成员只能是属性,函数,事件,索引器
    成员必须是public,不用写,也不能写
    
    访问修饰 关键字 接口名{}
    接口名 命名 一般以 I 为前缀
    
    接口使用:
    我们可以用一个类来继承已经定义好的接口:一对一,一对多,接口之间可以相互继承
    如果在继承关系中,这个类有继承其它类,这个基类要放在继承的第一位
    继承一个接口必须实现这个接口所有成员
    能让我们把物品按特定的功能统一管理

    m1w4d2_indexes

    索引器
    索引器可以让我们通过不同的索引号返回对应类型的多个属性
    索引器适用于除自动属性以外的所有属性特性
    索引号可以是任意类型
    索引器在通过类对象来访问和赋值 变量(类对象)[索引号]
    访问修饰 返回类型 this[索引号,索引号,索引号,索引号......]
    { get {return} set {value} }
    
    静态构造函数什么时候调用
    当我们访问静态成员的时候,先调用且只调用一次
    当我们创建对象的时候,先调用且只调用一次
    可以对静态字段做初始化使用的,静态的成员才会加载到内存中

    m1w4d2_operator

    重载运算符
    返回类型?,函数名(operator 运算符)?参数?
    public static i = i + 1;
    两个参数,任意类型
    返回类型,任意类型
    算数运算符 是双目运算符,参数必须是两个,任意类型,返回类型,任意类型
    关系运算符 是双目运算符,参数必须是两个,任意类型,返回类型是bool

    m1w4d3_delegate

    委托
    委托类型的定义
    委托是一个引用类型,存放着一个或者一组方法的引用
    方法的签名
    访问修饰 关键字(delegate) 对应方法的签名(返回类型 委托名 参数)
    
    委托类型的定义
    MyDelegate myDelegate;//这种形式用的比较多
    MyDelegate myDelegate1 = new MyDelegate(Max);//这种形式用的比较少
    
    赋值
    将委托的委托列表清空,然后将赋值的函数注册到委托列表
    如果我们将一个函数赋值到委托
    这个委托被调用时,等同与函数被调用
    赋值只需要函数(方法)名,不需要传参
    myDelegate = Max;//用的比较少
    
    注册
    如果我们将一个函数注册到委托
    相当于将函数注册到其委托列表
    这个委托被调用时,将调用到这个注册函数
    注册只需要函数(方法)名,不需要传参
    myDelegate += Min;//用的比较多
    
    注销
    注册就是将一个函数从委托的委托列表中移除
    仅移除最后一个注册的对应函数
    如果委托列表中没有对应的函数不会报错
    myDelegate -= Max;
    
    调用
    委托会将其 委托列表 中所有的函数按顺序执行
    通过委托我们只能取得最后的执行的函数的返回值
    委托调用时确定其参数,虽然委托中有多个函数,但只能使用一份参数
    委托可以通过 变量名(参数)调用,变量名.Invoke(参数)
    Console.WriteLine(myDelegate(3, 5));
    
    作为参数的应用
    委托可以做为另一个函数的参数使用
    当一个函数使用了委托参数时
    当其被调用时,我们可以直接放入一个对应委托,或者直接放入一个与委托同参同返回的函数参数
    
    如果一个函数和委托的约束的签名一致
    我们就可以把这个函数赋值或注册到委托

    m1w4d3_delegate1

    设计模式 在编程的过程中,前辈们为了解决特定的通用问题而总结出来的模式
    单例模式
    观察者模式 用于构建 事件处理系统
    通过一个被观察者去管理观察者
    被观察者 通过 事件(委托) 在状态改变时 调用所用注册过的 观察者方法
    
    1、委托外部调用不安全
    2、委托外部赋值不安全
    3、私有化之后,外部成员无法注册
    
    事件是对委托的进一步封装,约束了委托访问的作用域,允许事件在外部注册,但是不能赋值和调用
    通过在一个委托的前面加上event关键字可以定义一个事件

    m1w4d3_delegate3_lambert

    匿名委托和lambert表达式
    
    匿名委托
    匿名委托只能作为委托的值被使用
    缺陷
    匿名委托可读性差,建议匿名委托语句行数不宜过多,一句最佳
    匿名委托不可复用(违背封装原则)
    delegate (参数) {函数体}
    Sort(array, condition = delegate (int a, int b) { return a < b; });
    
    lambert表达式(匿名委托的进一步简写)
    lambert表达式只能作为委托的值被使用
    缺陷
    lambert表达式可读性差,建议匿名委托语句行数不宜过多,一句最佳
    lambert表达式不可复用(违背封装原则)
    
    lambert表达式可以让你不适用类型
    lambert表达式如果函数体只有一句语句,可以省略花括号,不写return,不写分号;
    lambert表达式在参数只有一个的情况下可以不用括号
    (参数)=> {函数体}
    Sort(array, (int a, int b) => { return a > b; });

    m1w4d4_list

    泛型集合
    在我们要使用泛型集合时
    首先我们要确认是否using System.Collections.Generic;
    
    泛型列表
    泛型列表允许我们做任意类型的列表,只需要在<>中填入相应类型
    list.Capacity; Capacity表示列表的实际长度
    list.Count; Count表示list中有多少个有意义的元素
    
    添加元素
    list.Add(123);
    
    访问元素
    通过索引器可以访问对应元素,但索引器的标号必须小于Count
    Console.WriteLine(list[0]);
    Console.WriteLine(list.Capacity);//初始为0.由Add创建
    
    删除元素
    list.RemoveAt(0);//移除指定下标中的元素
    list.Remove(999);//移除指定元素(从头查找到的)
    
    插入元素
    list.Insert();//在指定下标处,插入指定元素,原元素及其后的元素均排在插入元素的后方
    list.Insert(4, 999);
    
    查找元素
    从头查找
    int id = list.IndexOf(999);//根据元素从头查找,并返回找到的第一个元素的位置
    从尾查找
    int id1 = list.LastIndexOf(8);//根据元素从尾查找,并返回找到的第一个元素的位置

    m1w4d4_list1

    泛型列表排序IComparable
    用一个List排序
    泛型集合都是实现System.Collections.Generic;中对应接口的一些类型
    如果要实现一个自定义类的排序
    1、实现一个IComparable的接口
    2、调用Sort的重载,用一个接口类型IComparer
    3、调用Sort的重载,用一个委托类型Comparition
    需要一个和List装载的类型相同的一排序方法 int 函数名 (对应类型 对应类型)

    m1w4d5_dictionary

    声明变量
    Dictionary<char, string> dic = new Dictionary<char, string>();
    
    添加元素
    dic.Add('1', "");
    dic['2'] = "";
    
    修改一个元素
    dic['2'] = "";
    
    如果用户输入的key不在我们的范围内,会报错
    通过ContainsKey判定字典中是否包含了对应的key

    m1w4d5_list1

    泛型
    定义
    泛型是C#的一种特性,可以让我们将一种结构(类,接口)或者一种逻辑(函数)应用到所有类型
    如果我们要把一个类型或者方法写成泛型的,我们只需要在名称后面加上<>,<>中可以填入若干个类型替代符

    数学运算

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                //要求用户输入一个年份,然后判断是不是闰年?
                //闰年判断
                //年份能被400整除(2000)
                //年份能被4整除,但是不能被100整除(2008)
                Console.WriteLine("请输入一个年份");
                int year = int.Parse(Console.ReadLine());
                bool conditionA = year % 400 == 0;
                bool conditionB = year % 4 == 0;
                bool conditionC = year % 100 != 0;
                string message = (conditionA || (conditionB && conditionC)) ? "是闰年" : "不是闰年";
                Console.WriteLine(message);
                //找出100内所有素数。素数 / 质数:只能被1和这个数字本身整除的数字,1不是质数, 最小的质数是2。
                //如果你遇到一个复杂,要抽象其子问题
                //子问题:某一个数是不是质数
                for (int j = 2; j <= 100; j++)
                {
                    int num = j;
                    for (int i = 2; i <= num; i++)
                    {
                        if (i == num)
                        {
                            Console.WriteLine("{0}是一个质数", i);
                            break;
                        }
                        if (num % i == 0)
                        {
                            Console.WriteLine("{0}不是一个质数", i);
                            break;
                        }
                    }
                }
                //求100 - 999之间的水仙花数,例如:153 = 1 * 1 * 1 + 5 * 5 * 5 + 3 * 3 * 3
                //取某一位等于这个数 余这个位的上一位,如取百位,余千,然后与本位相除,如百位,除一百
                //abc = a * a * a + b * b * b + c * c * c;
                for (int i = 100; i <= 999; i++)
                {
                    int a = (i % 1000) / 100;
                    int b = (i % 100) / 10;
                    int c = (i % 10) / 1;
                    if (i == a * a * a + b * b * b + c * c * c)
                    {
                        Console.WriteLine(i);
                    }
                }
                //老师问学生,这道题你会作了吗?如果学生答“会了(y)”,则可以放学,
                //如果学生不会做(n),则老师再讲一遍,再问学生是否会做了。。。
                //直到学生会了为止,才可以放学
                //直到学生会了或老师给他讲了10遍还不会,都要放学
                bool ok = false;
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("老师问:这道题你会作了吗?");
                    Console.WriteLine("学生答:会了/不会做(y/n)");
                    while (true)
                    {
                        string ansanswer = Console.ReadLine();
                        if (ansanswer == "y")
                        {
                            Console.WriteLine("你真聪明"); ok = true; break;
                        }
                        else if (ansanswer == "n")
                        {
                            Console.WriteLine("老师又讲了一遍"); break;
                        }
                        else
                        {
                            Console.WriteLine("输入有误,请重新输入");
                        }
                    }
                    if (ok)
                    {
                        break;
                    }
                }
                Console.WriteLine("放学了");
                //在控制台上输出如下10 * 10的空心星型方阵
                //********** 画10个点*
                //**画第1个是 *,画第10个是 *,其他是空格
                //* *
                //**
                //**
                //**
                //**
                //**
                //**
                //**********
                for (int i = 0; i < 10; i++)
                {
                    for (int j = 0; j < 10; j++)
                    {
                        if (i == 0 || i == 9 || j == 0 || j == 9)
                        {
                            Console.Write("*");
                        }
                        else
                        {
                            Console.Write(" ");
                        }
                    }
                    Console.WriteLine();
                }
                //在控制台上输出如下10行的金字塔方阵
                //*
                //***
                //*****
                //*******
                //*********
                //***********
                //*************
                //***************
                //*****************
                //*******************
                //n 2n - 1 m - n m
                //行n 星数 空格 总行数m
                //1 1 9 10
                //2 3 8 10
                //3 5 7 10
                //4 7 6 10
                int m = 10;
                for (int j = 1; j <= 10; j++)
                {
                    int n = j;
                    int start = 2 * n - 1;
                    int space = m - n;
                    for (int i = 0; i < space; i++)
                    {
                        Console.Write(" ");
                    }
                    for (int i = 0; i < start; i++)
                    {
                        Console.Write("*");
                    }
                    Console.WriteLine();
                }
                //空心金字塔
                int m = 10;
                for (int j = 1; j <= 10; j++)
                {
                    int n = j;
                    int start = 2 * n - 1;
                    int space = m - n;
                    for (int i = 0; i < space; i++)
                    {
                        Console.Write(" ");
                    }
                    for (int i = 0; i < start; i++)
                    {
                        if (j == m)
                        {
                            Console.Write("*");//让最后一行输出星号
                        }
                        else
                        {
                            if (i == 0 || i == start - 1)
                            {
                                Console.Write("*");
                            }
                            else
                            {
                                Console.Write(" ");
                            }
                        }
                    }
                    Console.WriteLine();
                }
                //一只蜗牛在井底,井深30米,蜗牛每天爬3米,晚上滑2米,请问蜗牛要爬多少天,才能爬出井口
                //位置 snailPos
                //井深 well
                //天数 day
                //爬行速度 speed
                //掉落速度 drop
                int snailPos = 0;
                int well = 30;
                int day = 1;
                int speed = 3;
                int drop = 2;
                while (true)
                {
                    //蜗牛爬
                    snailPos += speed;
                    Console.WriteLine("第{0}天爬了{1}米", day, snailPos);
                    //爬完后立马问,到井口没
                    if (snailPos >= well)
                    {
                        break;
                    }
                    //晚上滑
                    snailPos -= drop;
                    //过了一天
                    day++;
                }
                Console.WriteLine(day);
            }
            //数组排序
            static int[] GetArrayRank(int[] array)
            {
                for (int i = 0; i < array.Length - 1; i++)
                {
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        if (array[j] > array[j + 1])
                        {
                            int temp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = temp;
                        }
                    }
                }
                return array;
            }
            //判断闰年
            static void GetYear(int year)
            {
                while (true)
                {
                    if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
                    {
                        Console.WriteLine("是闰年"); break;
                    }
                }
            }
        }
    }

     月考讲解

    C#基础:(共10题,每题2分)
    1、如果一个函数成员需要被子类使用且不需要提供其他类来使用,需要的修饰符【】
    A、private  
    B、protected
    C、internal //在当前项目中都可以访问;
    D、public
    
    2.在C#里,下列有关基本类的大小不正确的是【】
    A、int类型是4个字节
    B、bool类型是1个字节
    C、long类型是8个字节
    D、char类型是一个字节 //ascii是1个字节,unicode是2个字节,utf-8是3个字节 
    
    3.关于定义数组定义不正确的是【】
    A、int[] numbers={123456};
    B、int[] numbers=new int[6];
    C、int[][] numbers=new int[2][3];交错数组//交错数组第二个维度不能指定
    D、var a=new[]{1,2,3,4,5,6};
    
    4.有关数组说法正确的是 【】(多选)
    A、数组的内存是分配在栈中
    B、数组的索引从零开始的
    C、数组是一种数据结构,它包含若干相同的类型的变量
    D、数组可以是一维、多维、交错的
    
    5、以下关于C#中方法重载的说法正确的是【】。(多选)
    A.如两个方法名字不同,而参数的数量不同,那么它们可以构成方法重载
    B.如两个方法名字相同,而返回值的数据类型不同,那么它们可以构成方法重载
    C.如两个方法名字相同,而参数的数据类型不同,那么它们可以构成方法重载
    D.如两个方法名字相同,而参数的数量不同,那么它们可以构成方法重载
    
    6、在C#语法中,在派生类中对基类的虚函数进行重写,要求在声明中使用【】关键字。
    A.override
    B.new
    C.static
    D.virtual
    
    7、有关结构体和类的说法不正确的是 【】
    A、结构是值类型的,而类是引用类型的
    B、结构体不可以声明构造函数 //结构体可以声明构造函数,默认函数保留
    C、结构体直接继承System.ValueType类型 //System.ValueType是所有值类型的基类
    D、结构体可以继承接口 //结构体可以继承接口,但不可以继承类
    
    8.关于静态类说法正确的是【】 (多选)
    A、声明静态类,该类不能使用new关键字创建实例
    B、静态仅包含静态成员 //静态类包含常量成员
    C、静态类不能包含常量成员
    D、静态类是密封的 //静态类隐含是密封的
    
    9、有关继承需要用的关键字说法不正确的是【】
    A、virtual用于修饰方法、属性、索引器或事件,并使它们可以在派生类中被重写。
    B、virtual可以和static、abstractprivate、override修饰符一起使用。
    C、override关键字提供从基类继承的成员的新的实现,重写的基类方法必须是virtual、abstract、或override关键字修饰的。
    D、Sealed用于修饰类时,将会阻止其他类从该类派生
    
    10、在C#中,一个类【】
    A.可以继承多个类
    B.可以实现多个接口
    C.在一个程序中只能有一个子类
    D.只能实现一个接口
    
    算法题(共8题,每题的分数10分)
    1、写一个方法可以实现对一个数组实现升序排序: 使用冒泡排序实现数组内的排序
    
    2、写一个方法试着用最少的比较次数去寻找数组中的最大值和最小值
    
    3、写一个方法实现输入一个数组,实现一个函数,让所有奇数都在偶数前面
    
    4、猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个。第二天早上又将剩下的桃子吃了一半,还是不过瘾又多吃了一个。以后每天都吃前一天剩下的一半再加一个。到第10天刚好剩一个。问猴子第一天摘了多少个桃子?
    
    5、写一个方法可以求N到M之间的质数 N>0 M<200;
    
    6、多态实现求面积和周长(矩形和圆形)
    
    7、有若干只鸡兔同在一个笼子里,从上面数,有N个头,从下面数,有M只脚。问笼中各有多少只鸡和兔?
    
    8、小明带有一百文钱,去市场买鸡,公鸡5文钱,母鸡3文钱,小鸡1文钱3只; 问:小明要如何配比才能买一百只,他一共有几种方案
    using System;
    using System.Collections.Generic;
    namespace CSharp月考
    {
        class MainClass
        {
            public static void Main(string[] args)
            {
                #region 选择题
                // 1 B
                // 2 D
                // 3 C
                // 4 BCD
                // 5 CD
                // 6 A
                // 7 B
                // 8 ABD
                // 9 B
                // 10 B
                #endregion
                #region 第1题调用
                int[] nums = { 5, 7, 6, 9, 8 };
                string[] nums = { "abd", "abc", "bcd", "cbd", "bdc", "ab", "b" };
                SortArray(nums);
                SortArray(nums, (a, b) =>
                {
                    for (int i = 0; i < a.Length && i < b.Length; i++)
                    {
                        if (a[i] != b[i])
                        {
                            return a[i] - b[i];
                        }
                    }
                    return a.Length - b.Length;
                });
                foreach (var item in nums)
                {
                    Console.WriteLine(item);
                }
                #endregion
                #region 第2题调用
                int[] nums = { 5, 7, 6, 9, 8 };
                int max, min;
                if (GetMaXMin(nums, out max, out min))
                {
                    Console.WriteLine("Max : " + max + ", Min : " + min);
                }
                #endregion
                #region 第3题调用
                int[] nums = { 2, 1, 3, 5, 8, 10, 7, 2, 7, 4, 3, 1, 5 };
                Sort(nums);
                foreach (var item in nums)
                {
                    Console.WriteLine(item);
                }
                #endregion
                #region 第4题调用
                Console.WriteLine(Monkey(1));
                #endregion
                #region 第5题调用
                foreach (var item in GetPrimeNumber(0, 200))
                {
                    Console.WriteLine(item);
                }
                #endregion
                #region 第6题调用
                Shape[] shapes = { new Rectangle(5, 10), new Circle(5) };
                foreach (var item in shapes)
                {
                    Console.WriteLine(item.GetArea());
                    Console.WriteLine(item.GetLength());
                }
                #endregion
                #region 第7题调用
                int checkin, rabbit;
                if (GetNum(5, 14, out checkin, out rabbit))
                {
                    Console.WriteLine("鸡 :" + checkin + ", 兔 : " + rabbit);
                }
                #endregion
                #region 第8题调用
                BuyChecken(100, true);
                #endregion
            }
            #region 1.    写一个方法可以实现对一个数组实现升序排序: 使用冒泡排序实现数组内的排序
            static void SortArray<T>(T[] array)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        IComparable<T> comparable = array[j] as IComparable<T>;
                        if (comparable != null)
                        {
                            if (comparable.CompareTo(array[j + 1]) > 0)
                            {
                                T tmp = array[j];
                                array[j] = array[j + 1];
                                array[j + 1] = tmp;
                            }
                        }
                    }
                }
            }
            static void SortArray<T>(T[] array, Comparison<T> comparison)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    for (int j = 0; j < array.Length - 1 - i; j++)
                    {
                        if (comparison(array[j], array[j + 1]) > 0)
                        {
                            T tmp = array[j];
                            array[j] = array[j + 1];
                            array[j + 1] = tmp;
                        }
                    }
                }
            }
            #endregion
            #region 2.  写一个方法试着用最少的比较次数去寻找数组中的最大值和最小值
            static bool GetMaXMin(int[] array, out int max, out int min)
            {
                if (array == null || array.Length == 0)
                {
                    max = min = 0;
                    return false;
                };
                // 把数组两两分组 小的放左边 大的方右边        比较次数 n/2 次
                // 最小值在左边找                          比较次数 n/2 次
                // 最大值在右边找                          比较次数 n/2 次
                // 总的比较次数                                  3n/2 次
                // 优化:不做交换 直接和每组比 每组比较的次数 3次
                max = min = array[0];
                // 长度为偶数
                if (array.Length % 2 == 0)
                {
                    for (int i = 0; i < array.Length; i += 2)
                    {
                        if (array[i] > array[i + 1])
                        {
                            if (array[i] > max) max = array[i];
                            if (array[i + 1] < min) min = array[i + 1];
                        }
                        else
                        {
                            if (array[i + 1] > max) max = array[i + 1];
                            if (array[i] < min) min = array[i];
                        }
                    }
                }
                else  // 长度为奇数
                {
                    for (int i = 0; i < array.Length - 1; i += 2)
                    {
                        if (array[i] > array[i + 1])
                        {
                            if (array[i] > max) max = array[i];
                            if (array[i + 1] < min) min = array[i + 1];
                        }
                        else
                        {
                            if (array[i + 1] > max) max = array[i + 1];
                            if (array[i] < min) min = array[i];
                        }
                    }
                    if (max < array[array.Length - 1]) max = array[array.Length - 1];
                    if (min > array[array.Length - 1]) min = array[array.Length - 1];
                }
                return true;
            }
            #endregion
            #region 3.  写一个方法实现输入一个数组,实现一个函数,让所有奇数都在偶数前面
            static void Sort(int[] array)
            {
                // 两个指针
                // 左边的找到第一个偶数
                // 右边的找到第一个奇数
                // 如果两个指针满足  左边的 < 右边的 就交换这两个数
                int left = 0;
                int right = array.Length - 1;
                while (left < right)
                {
                    // 找左边的偶数
                    while (left < right)
                    {
                        if (array[left] % 2 != 0)
                        {
                            left++;
                        }
                        else break;
                    }
                    // 找右边的奇数
                    while (left < right)
                    {
                        if (array[right] % 2 == 0)
                        {
                            right--;
                        }
                        else break;
                    }
                    if (left < right)
                    {
                        int tmp = array[left];
                        array[left] = array[right];
                        array[right] = tmp;
                    }
                }
            }
            #endregion
            #region 4.  猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个。第二天早上又将剩下的桃子吃了一半,还是不过瘾又多吃了一个。以后每天都吃前一天剩下的一半再加一个。到第10天刚好剩一个。问猴子第一天摘了多少个桃子?
            //          7        2*7 + 1        15
            //          8        2*3 + 1        7
            //          9        2*1 + 1        3
            //          10       1              1
            static int Monkey(int day)
            {
                if (day > 10) return 0;
                else if (day == 10) return 1;
                else return 2 * (Monkey(day + 1) + 1);
            }
            #endregion
            #region 5.  写一个方法可以求N到M之间的质数 N>0 M<200;
            static List<int> GetPrimeNumber(int left, int right)  // (]
            {
                List<int> primeNumber = new List<int>();
                int start = left < right ? left : right;
                start = start >= 2 ? start : 2;
                int end = left < right ? right : left;
                end = end >= 2 ? end : 2;
                for (int i = start; i < end; i++)
                {
                    // 判断每一个数字 i 是否是质数
                    bool isPrimeNumber = true;
                    // 除了1和自己 能被其他数字整除就不是质数
                    for (int j = 2; j < i; j++)
                    {
                        if (i % j == 0)  // 能被其中一个数字整除了 就不是质数了
                        {
                            isPrimeNumber = false;
                            break;
                        }
                    }
                    if (isPrimeNumber)
                    {
                        primeNumber.Add(i);
                    }
                }
                return primeNumber;
            }
            #endregion
            #region 6.  多态实现求面积和周长(矩形和圆形)
            abstract class Shape
            {
                public abstract int GetArea();
                public abstract int GetLength();
            }
            class Rectangle : Shape
            {
                int width;
                int height;
                public Rectangle(int width, int height)
                {
                    this.width = width;
                    this.height = height;
                }
                public override int GetArea()
                {
                    return this.width * this.height;
                }
                public override int GetLength()
                {
                    return (width + height) * 2;
                }
            }
            class Circle : Shape
            {
                int radius;
                public Circle(int radius)
                {
                    this.radius = radius;
                }
                public override int GetArea()
                {
                    return (int)(radius * radius * Math.PI);
                }
                public override int GetLength()
                {
                    return (int)(Math.PI * 2 * radius);
                }
            }
            #endregion
            #region 7.  有若干只鸡兔同在一个笼子里,从上面数,有N个头,从下面数,有M只脚。问笼中各有多少只鸡和兔?
            static bool GetNum(int head, int foot, out int checkin, out int rabbit)
            {
                if (foot % 2 != 0 || foot < 2 * head) {
                    checkin = rabbit = 0;
                    return false;
                }
                // 二元一次方程  假设x只鸡, y只兔子
                //foot = x * 2 + y * 4;     
                //head = x + y;              => x = head - y
                // => foot = (head - y) * 2 + y * 4
                // => foot = head * 2 - 2 * y + y * 4
                // => y = (foot - head * 2)/2
                rabbit = (foot - head * 2) / 2;
                checkin = head - rabbit;
                return true;
            }
            #endregion
            #region 8.  小明带有一百文钱,去市场买鸡,公鸡5文钱,母鸡3文钱,小鸡1文钱3只; 问:小明要如何配比才能买一百只,他一共有几种方案
            // 100文钱                                 只
            //         公鸡     5         1            x        5x
            //         母鸡     3         1            y        3y
            //         小鸡     1         3            z        z/3
            // x  + y  + z    = 100
            // 5x + 3y + z/3 <= 100
            static void BuyChecken(int totalMoney, bool allin = false)
            {
                int num;   // 买鸡的数量
                int cost;  // 花费
                // 买小鸡
                for (int i = 0; i <= totalMoney * 3; i+=3)          // 小鸡的个数
                {
                    // 买公鸡
                    for (int j = 0; j <= totalMoney/5; j++)
                    {
                        // 买母鸡
                        for (int k = 0; k <= totalMoney/3; k++)
                        {
                            num = i + j + k;
                            cost = i / 3 + 5 * j + 3 * k;
                            if(allin)
                            {
                                if (num == 100 && cost == 100)
                                {
                                    Console.WriteLine($"小鸡:{i}只, 公鸡{j}只, 母鸡:{k}只");
                                }
                            }
                            else
                            {
                                if (num == 100 && cost <= 100)
                                {
                                    Console.WriteLine($"小鸡:{i}只, 公鸡{j}只, 母鸡:{k}只");
                                }
                            }
                        }
                    }
                }
            }
            #endregion
        }
    }
  • 相关阅读:
    最权威的 Android Oreo 新特性详解
    【送书福利】第一次送书活动(总共10本)
    【资源篇】Python那么火,你还不知道如何人门?
    不忘初心,方得始终 ,让我们一起学习成长,感谢有你!
    搭建环境篇 | 运行第一个Java Web 项目
    为什么我们需要看技术公众号文章?
    手把手教学APK反编译实现源码阅读
    分享一款 Google Pixel 2 独家动态壁纸
    了解CoordinatorLayout,在项目中运用
    jdk 与 jre的区别
  • 原文地址:https://www.cnblogs.com/vuciao/p/10362610.html
Copyright © 2020-2023  润新知