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-9:48-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() + "\r\n"); Console.WriteLine("\r\n"); 2、用单个字符来分隔: string str3 = "aaajbbbjccc"; string[] sArray3 = str3.Split('j'); foreach (string i in sArray3) Console.Write(i.ToString() + "\r\n"); Console.WriteLine("\r\n"); 3、用多个字符来分隔: string str2 = "aaajbbbscccjdddseee"; string[] sArray2 = str2.Split(new char[2] { 'j', 's' }); foreach (string i in sArray2) Console.Write(i.ToString() + "\r\n"); Console.WriteLine("\r\n"); 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; } } } } }