01 C#基础
第一天
.net平台(中国移动互联网平台):
.net框架(信号塔):
CLR(公共语言运行时)
.Net类 库
我们使用的语言是——C#
2.解决方案项目与类的关系:
解决方案:公司
项目:部门
类:员工
3.Program.cs中的各个组成部分:
引用命名空间:
京东->京东在线商城项目->顾客类
淘宝->淘宝在线商城项目->顾客类
高端霸气公司->老赵牛X项目->顾客类
第二天
单行注释//
多行注释/* */
文档注释 /// (多用来说明类)
快捷键
快速格式化代码的快捷键
Ctrl+K+D
删除一行
Ctrl+X
按着Shift键然后按上下键来选定一行或多行
添加注释Ctrl+K+C
关闭注释Ctrl+K+U
代码块
#region
#endregion
鼠标指着int然后按F1
数据类型
Int
String
Char 必须用单引号‘‘
Double 15-16位
Decimal 28-29位 精度更高 多用于金钱的计算 后面必须加个m小写或大写
如果没有后缀 m,则数字将被视为 double 类型并会生成编译器错误。Without the suffix m, the number is treated as a double and generates a compiler error.
变量的使用规则
现阶段变量起名以字母开头,并以字母数字下划线来结尾
命名规范:
camelCase 首单词首字母小写,其他的都大写 多用于给变量命名
Pascal 每个单词的首字母大写,其余字母小写,多用于给类或方法命名
给字段命名加_
占位符:
先挖个坑,再填个坑。
Console.WriteLine("第一个数字是{0},第二个数字是{1},第三个数字是{2}",n1,n2,n3);
输出顺序,按照挖坑的顺序输出。
异常
异常是指语法上并没有任何错误,只不过在程序运行的期间由于某些原因出现的问题使程序不能再正常的运行。
交换变量 不能使用第三方变量
N1 = n1-n2;
N2 = n1+n2;
N1 = n2-n1;
接收用户在控制台的输入
Console.ReadLine();
转义字符
\n 回车
\b 退格,删除前一个字符
这个\n只能在winform或控制台里有用,这样写在Windows的OS下桌面上的这个1111.txt并没有这个换行,在Mac操作系统下是有换行的,如果想在Win下面有换行需要写\r\n。
@符号——1.取消字符串中’\’的转义作用,使其单纯表示为一个\
2.保留原字符串格式输出
类型转换
我们要求等号两边参与运算的操作数类型必须一致,如果不一致,满足下列条件会发生自动转换类型,或称之为隐式类型转换。
- 两种类型兼容 例如int和double兼容(都是数字类型)
- 目标类型大于源类型 (小的转大)
总结:
自动类型转换:int->double
显式类型转换:double->int
大的转小的需要强制类型转换。
Double d = n1*1.0 / n2;
式子右边 由于乘了1.0将某一个操作数提升为了double类型,整体都会进行提升为double类型。
保留两位小数点{0:0.00}
第三天
使用Convert转换
条件:面儿上必须要过得去。
//显示类型转换、自动类型转换
//Int -- double double – int
可能会丢失精度。
string a = “123”;
类型如果相兼容的两个变量,可以使用自动类型转换或强制类型转换,
但式如果两个类型的变量不兼容,比如string与int或string与double,
这个时候我们可以使用一个叫做Covert的转换工厂进行转换。
到目前学了三种类型转换,显式类型转换,隐式类型转换,使用Convert进行转换。
加加减减
表达式,运算符。
Int a = 5;
Int b = a++ + ++a*2 + --a + a++;
5 + 7*2 + 6 + 6
此时a为7。
对于像++或—这样只需要一个操作数就能完成的运算,我们称之为一元运算符
+ - * / % 对于这些需要两个或以上才能完成运算的操作符,我们称之为二元运算符
一元运算符的优先级要高于二元运算符。
如果在一个表达式当中,既有一元运算符,又有二元运算符,我们首先计算一元运算符。
int number = 10;
int result = 10 + ++number;
所以上式中的int b是从左到右进行计算。
关系运算符 > < == …..
返回值是true或false
逻辑运算符 &&逻辑与 ||逻辑或 !逻辑非
由逻辑运算符连接的表达式叫逻辑表达式
&&与&的区别
bool b = 5<3 && 5>3
&&的话,如果前面那个啥了后面就不计算了,如果是一个&后面会继续计算,所以一般都用两个符号。
复合赋值运算符 += -+ *= /=
year % 400 == 0 || year % 4 == 0 && year % 100 != 0;
在一个表达式中既有逻辑与又有逻辑或,先算逻辑与,不过防止乱一般我们都用括号。
if,else if…
else总是跟着离他最近的那个if。
判断用户名密码是否正确(骚操作)
Console.WriteLine("请输入用户名");
string admin = Console.ReadLine();
Console.WriteLine("请输入密码");
string pwd = Console.ReadLine();
if (admin == "admin" && pwd == "888888")
{
Console.WriteLine("登陆成功");
}
else if (admin == "admin")
{
Console.WriteLine("密码错误");
}
else if (pwd == "888888")
{
Console.WriteLine("用户名错误");
}
else {
Console.WriteLine("用户名和密码都错了");
}
Console.ReadKey();
第四天
异常捕获
我们在程序中经常会出现各种各样的异常,你如果想让你的程序变得坚强一些,
在你的代码中应该经常性的使用try…catch来进行异常捕获。
哪行代码有可能出现异常,你就踹他一脚。
语法:
try
{
可能会出现的异常代码;
…
…
}
catch
{
出现异常后要执行的代码
}
执行过程:如果try中的代码没有出现异常,那么catch中的代码不会执行,
如果try中的代码出现了异常,哪怕这行出现异常的代码后面还由一百行代码都不会执行了。
而是直接跳到catch中执行代码。
try 和 catch之间不能有其它的代码。
变量的作用域
变量的作用于就是你能够使用到这个变量的范围。
变量的作用于一般从声明它的那个括号开始到那个括号所对应的结束的括号结束。
在这个范围内,我们可以访问并使用变量,超出这个范围就访问不到了。
Switch-case
用来处理多条件的定值的判断。
语法:
Switch(变量或者表达式的值)
Case 值1:要执行的代码;
Break;
Case 值2:要执行的代码;
Break;
Case 值3:要执行的代码;
Break;
……
Default:要执行的代码;
Break;
执行过程:程序执行到switch处,首先将括号中的变量或表达式的值计算出来,
然后拿着这个值依次跟每个case后面所带的值进行匹配,一旦匹配成功,则执行case所带的代码,执行完成后,遇到break,跳出switch-case结构。
如果,跟每个case所带的值都不匹配。就看当前这个switch-case结构中是否存在default,如果有default,则执行default中的语句,如果没有default,则该switch-case结构什么都不做。
Switch 与 if else-if的区别
都可以做多条件判断,if else-if用来做区间判断。
而Switch用来做定值的判断。
骚操作
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
day = 31;
break;
case 2:
//由于2月有平年和闰年的不同 所以首先要判断一下当年是不是闰年
if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
{
day = 29;
}
else
{
day = 28;
}
break;
default:
day = 30;
break;
}
循环结构
While 特点:先判断再执行,有可能一遍循环都不执行。
Do..while
do
{
}while();
特点: 程序首先会执行do中的循环体,执行完成后,去判断do-while循环的循环条件,如果成立,则继续执行do中的循环体,如果不成立,则跳出do-while循环。至少执行一遍。
for
break语句 => 跳出当前循环
第五天
程序调试
写完一段程序后,想看一下这段程序的执行过程。
当你写完这段从程序后,发现程序并没有按你想象的样子去执行。
1) F11逐语句调试(单步调试)
即将要被执行,但是没有执行。
调试—窗口—监视
2) F10逐过程调试
(这里先不讲)
3) 断点调试
程序运行到断点处就不再执行了
For循环
打完for后敲两下tab就能快速生成。
//下面打印出所有的乘法口诀表
for (int i = 1; i <= 9; i++)
{
for (int j = 1; j <= 9; j++)
{
Console.Write("{0}*{1}={2}\t", i, j, i * j);
}
Console.Write("\n");
}
Console.ReadKey();
数字的转换
把用户输入的数字转换成我们想要的数字类型,可以用
1.Convert.ToInt32(“3”)
2.int.Parse(“3”)
Convert.ToInt32其实内部上就是在调用int.parse。
还有double.parse decimal.parse..
- int.tryparse
尝试着将一个字符串转换成int类型
Int number = 0;
//参数 返回值
Bool b = int.tryparse(“123abc”,out number);
Console.WriteLine(b);
Console.WriteLine(number);
//方法 或者 函数?
Console.ReadKey();
后面会具体讲。
Continue
三元表达式
A?B:C
注意:表达式1一般为一个关系表达式
如果表达式1的值为true,那么表达式2的值就是整个三元表达式的值。
如果表达式1的值为false,那么表达式3的值就是整个三元表达式的值。
注意:表达式2的结果类型必须和表达式3的结果类型一致,并且也要跟整个三元表达式的结果类型一致。
随机数
//产生随机数
//1、创建能够产生随机数的对象
Random r = new Random();
//2、让产生随机数的这个对象调用方法来产生随机数
//这里返回的是一个int类型的数字
Console. WriteLine(r.Next(1,10));
Console.ReadKey();
//这里产生的是左闭 、右开区间。
第六天
总结下运算符:
常量
const 变量类型 变量名= 值
什么时候会用到常量?
枚举
语法:
[public] enum 枚举名
{
值1
值2
值3
……
}
public:访问修饰符,公开的访问修饰符,哪都可以访问。
enum: 关键字,声明枚举的关键字
枚举名:要符合Pascal命名规范
//将枚举声明到命名空间的下面,类的外面,表示这个命名空间下所有的类都可以使用这个枚举。
枚举就是一个变量类型,int double string decimal 一样
只是枚举声明、赋值、使用的方式跟那些普通的变量类型不一样。
枚举类型可以强制转换成int类型, int类型也可以强制转换成枚举类型.
枚举类型也可以转换成string类型。
//所有的类型都能够转换成string类型
*string转换成枚举类型
string s = "1";
//将s转换成枚举类型
//Convert.toInt32() int.parse int.tryparse
//调用parse()方法的目的就是为了让他帮助我们将一个字符串转换成
//对应的枚举类型
QQState state = (QQState)Enum.Parse(typeof(QQState),s);
Console.WriteLine(state);
Console.ReadKey();
我们可以将一个枚举类型变量跟int类型和string类型互相转换。
枚举类型默认是跟int类型相互兼容的,所以可以通过强制类型转换的语法互相转换。
当转换一个枚举中没有的值的时候,不会抛异常,而是直接将数字显示出来。
枚举同样也可以跟string类型互相转换,如果将枚举类型转换成string类型,则直接调用ToString();如果将字符串转换成枚举类型则需要下面这样一行代码:
(要转换的枚举类型) Enum.Parse(typeof(要转换的枚举类型),”要转换的字符串”);
如果转换的字符串是数字,则就算枚举中没有,也不会抛异常。
如果转换的字符串是文本,如果枚举中没有,则会抛出异常。
小练习:
namespace 枚举
{
public enum QQState
{
Online=1, //0
Offline, //1
Leave, //2
Busy, //3
Qme //4
}
class Program
{
static void Main(string[] args)
{
//枚举练习
//提示用户选择一个在线状态,我们接收,并将用户的输入转换成枚举类型。
//在此打印到控制台中
Console.WriteLine("请选择您的在线状态 1--OnLine 2--OffLine 3--Leave 4--Busy 5--Qme");
string input = Console.ReadLine();
switch (input)
{
case "1": QQState s1 = (QQState)Enum.Parse(typeof(QQState), input);
Console.WriteLine("您选择的在线状态是{0}", s1);
break;
case "2": QQState s2 = (QQState)Enum.Parse(typeof(QQState), input);
Console.WriteLine("您选择的在线状态是{0}", s2);
break;
case "3": QQState s3 = (QQState)Enum.Parse(typeof(QQState), input);
Console.WriteLine("您选择的在线状态是{0}", s3);
break;
case "4": QQState s4 = (QQState)Enum.Parse(typeof(QQState), input);
Console.WriteLine("您选择的在线状态是{0}", s4);
break;
case "5": QQState s5 = (QQState)Enum.Parse(typeof(QQState), input);
Console.WriteLine("您选择的在线状态是{0}", s5);
break;
}
Console.ReadKey();
}
}
}
结构
结构可以帮助我们一次性声明多个不同的变量。
语法:
[public] struct 结构名
{
成员://字段
}
变量:变量只能赋一个值
字段:字段可以赋多个值
为了区别于字段和变量
我们给字段加下划线_name区别于name
(回想一下枚举是怎么定义的..[public] enum。。。)
数组
一次性存储多个相同类型的变量。
语法:
数组类型[] 数组名称 = new 数组类型[数组长度];
数组的长度一旦固定了就不能再被改变了。
int类型数组默认值都是0
string类型数组默认值是null
null与” ”
null不是空,null是指根本没有在内存中开空间 “”则是开空间了
//数组类型[] 数组名 = new 数组类型[数组长度]
int[] nums = new int[10];
//数组的声明方式
int[] numsTwo = { 1, 2, 3, 4, 5, 6 };
//deprecated;
int[] numsThree = new int[3] { 1, 2, 3 };//deprecated;
int[] numsFour = new int[] { 1, 2, 3, 4, 5 };//deprecated; ‘
冒泡排序
冒泡排序比较简单,这里就不介绍了。
Array.sort(nums); //升序排列的
Array.reverse(nums) //对数组进行反转
函数与方法
函数的语法:
[public] 访问修饰符 static 返回值类型 方法名([参数列表])
{
方法体:
}
public:访问修饰符,公开的,公共的,哪都可以访问
static:静态的
返回值类型: 如果不需要写返回值,写void
方法名:Pascal 每个单词的首字母大写,其余字母小写
参数列表:完成这个方法所必须要提供给这个方法的条件。
如果没有参数,小括号也不能省略。
方法写好后,如果想要被执行,必须要放在Main()函数中调用。
如何执行一个方法:
类名、方法名。{[参数]}
***在某些情况下,类名是可以省略的,
如果你写的方法跟Main()函数同在一个类中,这个时候,类名可以省略。
return的作用
- 在方法中返回要返回的值
- 立即结束本次方法
第七天
方法的定义:
[访问修饰符][static] 返回值类型 方法名()
{
方法体;
}
命名规则:
·方法名开头大写(Pascal),参数名开头小写,参数名、变量名要有意义。
·方法的调用,对于静态方法,调用有两种方式
·如果在同一个类中,直接写名字调用就行了
·或者类名、方法名();
·return可以立即退出方法。
变量的作用域(只讲局部变量)
1.我们在Main()函数中,调用Test()函数,我们管Main()函数称之为调用者,管Test()函数称之为被调用者,
如果被调用者想要得到调用者的值。
1)传递参数
2)使用静态字段来模拟全局变量
如果调用者想要得到被调用者的值,
1) 返回值
2.不管是实参还是形参,都是在内存中开辟了空间的。
//读取输入的整数,定义成方法,多次调用
//(如果用户输入的是数字,则返回,否则提示用户重新输入)
- 方法的功能一定要单一。
GetMax(int n1,int n2)、判断闰年(方法中不要有判断闰年和getmax这两个功能)
方法中最忌讳的就是提示用户输入。
(这样方法就限定死了,不方便复用)
out、ref、params
如果在一个方法中返回多个相同类型的值的时候可以考虑返回一个数组,但是考虑返回多个不同值的时候,数组就不行了,这个时候我们可以考虑out参数。
out参数
侧重于在一个方法中可以返回多个不同的值。
用法:
public static void Fun(out string num)
{
num = “asdasd”;
//out的参数在方法中必须被赋值
}
public static void Main(string[] args)
{
string num;
Fun(out num);
//这样num就赋值给了外面的num
}
ref参数
能够将一个变量带入一个方法中进行改变,改变完成后,再将改变后的值带出方法
ref参数要求在方法为必须为其赋值,而方法内可以不赋值。
param可变参数
将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理。
params可变参数必须是形参列表中的最后一个元素。
(一个参数列表中只能出现一个可变参数)
方法的重载
方法的重载指的就是方法的名称相同,但是参数不同。
方法的重载与返回值没有关系。
Console.WriteLine()其实就是重载..
Console.WriteLine(1);
Console.WriteLine(true);
Console.WriteLine(‘C’);
Console.WriteLine…
参数不同,分为两种清空
1)、如果参数的个数相同,那么参数的类型就不能相同
2)、如果参数的类型相同,那么参数的个数就不能相同
6.方法的递归
方法自己调用自己。
找出一个文件夹中所有的文件。
需要一个方法,能够找到一个指定的文件夹下所有的文件。
递归