·.Net:
1.概念:
.NET Framework(.net 平台):
开发语言:C#(sharp) VB F# C++
开发工具(编译器):Visual Studio
系统类库:强大的类库支持 (全家桶 大而全)
2..NET 可以做什么:
C/S 桌面应用(工控 上位机)
B/S 网站应用
服务器端开发(微信小程序/APP/结合游戏引擎)
3.环境安装:
msdn.我告诉你(帮助小网站)
VS2019安装:在线安装
第一次进入 选择 开发语言 C#
4.第一个 Hello World!
1 进入界面 选择 创建新项目
2 创建控制台项目 (黑框框)
搜索 控制台项目(.net framework)
3 配置项目名称
5.认识控制台应用程序结构:
.sln 解决方案 最顶层的名称 一个解决方案可以有多个项目
启动项目 入口
program.cs 程序类文件 写代码的地方
.csproj 项目文件 存放了一些项目信息
.config 项目配置文件 存放配置信息
bin文件夹 项目输出文件夹 生成一个exe文件
代码结构:
//默写
using System: //引用命名空间 调用一些空间
//命名空间
namespace 解决方案名称
{
//类
class program
{
//程序入门 Main方法
static void Main(string []args)
{
//写代码的地方
}
}
}
控制台输出语法:
Console.WriteLine();// cw tab tab 快捷方式
Console.WriteLine("输出的内容");
Console.ReadLine();//接收键盘输入 光标闪烁
启动:
F5快捷键 绿色 启动按钮
//斜杠 注释
\
程序逻辑:
输出 输入
程序的三大基本结构(顺序|选择|循环)
数组
方法 string(字符串类型)
2:输出语句:
Console.Write(); //在屏幕上输入一段内容
字符:"你好" 'X'
Console.WriteLine(); // 在屏幕上输入一段内容 换行
特殊的字符
\n 换行 @ 去除特殊符号的含义 @"你\n好"
\t 空一格制表符位置
占位符输出/格式化输出:
Console.Write("内容{0}{1}",值0,值1);
格式化输出:
C 货币 {0:C2} -->2000 -->¥2.000.00
D 数值 {0:D3} -->5 -->005
补位 {0,3} -->5 --> 5
补位 {0,-3} -->5 -->5
X 16进制 {0:X} -->255 -->FF
3:编译型/解释型差别
C#/Java 编译型语言 检查所有代码是否能通过全部通过才能进入下一步
HTML/js 解释型语言 解释一条就执行一条
4.输入:
Console.ReadLine(); //从键盘输入数据
注意:当执行到这句话 进程会卡在这里 等待输入直到接收到 回车
才会继续
计算机 处理数据
5.变量(!):
常量:固定不变的数据就是常量 “今天的天气很好今天是2021年9月10号”
变量:可以在一定范围内发生改变的量
变量的三要素:
数据类型
变量名称
变量值
’盒子’ 内存 装数据
不同类型的盒子 装不同的东西 数据类型
盒子东西 装的东西 变量的值
数据类型:为了可以让不同的数据存放在不用的空间中 长度不同
C#数据类型(!)
整数 byte short int long
数据类型(数字)
小数(浮点数) float double
值类型 字符类型 char (单字符类型'')
布尔类型 bool
结构体类型 struct
枚举类型 enum
引用类型 类(class) 数组([]) 接口(interface) 委托
string
变量名称:
方便使用变量所取的名字
命名规则: 字母 数字 下划线组成 不能数字开头
建议:驼峰命名法 不要单字母和拼音
stuName myshoolName
变量值:
变量中具体存放的数据 必须和数据一样
语法:
数据类型 变量名称 = 值;
变量输出:
Console.Write("内容{0},内容{1}",变量1,变量2); //推荐做法
Console.Write("内容"+变量1+",内容"+变量2);
数据类型转换(难点):
同类型之间 小数据转成给大数据 可以直接转换,不需要任何操作
int num = 20;
long num2 = num; //可以赋值就可以
不同类型 或者 大数据转给小数据 必须强制转换
万能转换函数
Convert.ToXxx(数据)
注意:能不能最终转换成功还是要看数据 是否匹配
变量.ToString() -->转成字符串
特别:
ANSCI码 字符在计算机中都对应存储了一个数字
a -->97
A -->65
0 -->48
运算符:
赋值运算符
= 变量 = 值; //把右侧的数据赋值给左边
算术运算符:
+
-
*
/ 整数相除操作会自动取整
% 取余数 10%3=1 10%2=0
自增自减运算符(难点):
++:自增1
--:自减1
++写前面 先做+1操作 在做其他事情
++写后面 先做其他事情 在做+1操作
--写前面 先做-1操作 在做其他事情
--写后面 先做其他事情 在做-1操作
比较运算符:
>
<
==
!=
>=
<=
特点: 比较完成之后返回的是 bool 类型的数据 true false
逻辑运算符:
或 与 非
与(&&) 条件1&&条件2&&条件3&&.......
所有条件 如果都是 true 结果就是 true 否则就为 false
或(||) 条件1||条件2||条件3||.....
所有条件 如果有一个为 true 结果就是 true 全部为 false 才为 false
非(!) 取反
!true --> false
程序的三大基本结构:
1.顺序结构:默认情况,从上到下,从右到左,执行代码
2.选择结构(分支结构):根据不同的条件(情况),选择执行不同的代码
3.循环结构(重复):根据不同的条件(情况),重复执行不同的代码
选择结构:
分类:1.非此即彼的简单if结构
2.多重if结构(else if)
3.单点等着判断(switch)
1:简单 if 结构
语法:
if(条件)
{
//条件成立才执行的代码
}
注意:条件必须是能够返回 true 或者 false 的语句
条件 往往使用都是 比较运算符
if(条件)
{
//条件成立执行此处代码
}
else //否则
{
//条件不成立,执行此处代码
}
多个条件之间,可以使用,逻辑运算符 进行链接
&& || !
&& 并且 所有条件都为 true 才成立
|| 或者 只要一个 true 就成立
! 取反
多重 if :
如果有多个条件需要判断,条件区间,使用多重if结构
if(条件1)
{
}else if(条件2)
{
}else if(条件3)
{
}else if(条件4)
{
}
.......//加多个条件
else
{
//以上条件都不成立
}
单点等值判断:
作用和多重if类似,它只能判断相等
语法:
switch(要判断的变量) //开关/分支/交换
case 值1: //情况1
操作1;
break; //中断 停止
case 值2:
操作2;
break;
case 值3:
操作3;
break;
.....//添加多个条件
default: //默认值
//上面所有数据不满足,则执行此处的操作
break;
注意: break; 语句 必须添加 c#直接报错
只能做等值判断
选择结构:
1.特殊运算符:?
string str = age>18?"可以去网吧":"不可以去网吧";
布尔类型表达式 ? "条件成立执行此处操作":"不成立执行此处操作";
2.选择结构短路问题(难点)
短路: 计算机为了节约代码的执行时间,会跳过某些没有意外的代码
&& ||
&&:条件1 && 条件2 && 条件3 && 条件4 ......
必须全部为真,才为真
如果有一个条件为假 计算机会直接忽略后面所有语句
||:只要一个为真,全部为真
如果有一个条件为真,计算机就会忽略后面的所有语句
调试:
程序员在编译环境中可以通过一步步查看代码分析代码中的问题
"卡住"设置断点: break point 代码运行到设置了断点的位置 会停住
单步运行:让代码在我们的指挥下一步一步执行
F11 逐语句 运行
观察变量的值(重要):
局部变量窗口 或者 光标移动到变量身上 查看是否变量值正确了
F5:直接启动 有断点会卡住
ctrl+F5 :不调试启动 不会命中断点
语法错误/运行时异常:
语法错误:编写代码时出现的问题,直接有红线提示,无法通过编译
运行时异常:代码没有语法错误,但是在运行过程中出现问题(写代码不严谨)
循环结构:
语法:
while(条件)
{
//条件成立执行此处代码
}
while://当
分类: while do-while for 三种循环
作用:让程序不断重复的去执行某段代码
问题:让循环在指定情况停下来
语法学习:
while:循环
while(布尔类型表达式)
{
//当条件成立 则循环 执行此处代码
}
通常希望执行指定次数
int num = 0;
while(num<次数)
{
//操作
num++;
}
循环中退出语句
break continue goto
break :中断,遇到break 直接 结束循环 跳出
再循环中做完某些操作之后需要直接结束循环 使用 break
goto(C#特有 不建议使用):
直接跳到指定位置(容易引起代码阅读问题 只用在跳深层次循环)
continue:继续 退出 只退出当前这以一次循环 会继续下一次循环
这一次循环里面的后面所有代码不执行了 直接进入下一轮
for 循环死循环 :
for(;true;){
}
注意: while 可以实现的 for 循环都可以实现,只不过换了一种写法
更简洁 推荐执行指定次数循环时 使用 for
do-while 循环:
特点:先执行一次操作之后 再根据循环条件 判断是否继续执行
while 和 for 都可能会出现条件不成立 循环一次都不做
语法:
do{
//循环的操作
}while(循环条件);
总结:
for / while :先判断,在操作的循环 for(建议)
do-while:先执行 后操作(至少执行一次)
循环的嵌套结构:
练习:
数组:
值类型/引用类型
变量缺陷在需要使用大量,很多数据存储时变量显得很冗余麻烦
定义:
内存中一段连续的空间,用来保存数据类型相同的数据
数组的组成:
数据类型:表明这个数组中可以存放什么样的数据
数组名称:通过名称找到这个数组使用里面的数据
数组下标(索引):每个空间的编号,方便具体的 找到数组中的某一个数据
数组长度:表明数组一共可以放多少个数据,总长度意思
语法:
1.声明数组:
数据类型 [] 名称;
2.实列化数组
名称 = new 数据类型[长度];
注意!!!
数组在使用前必须先初始化,初始化的作用就是分配空间,给默认值
举例:
int [] age;
age = new int[5];//初始化
合二为一:
数据类型[]名称=new 数据类型[长度];//推荐做法
int []age = new int[5];
3.访问数组中的数据
注意:
必需结合下标一起访问数据
数组名[下标]
数组是有默认值:
string --> null int/double/long--->0 bool--->false
一定别越界 下标范围 0~长度-1
4.数组的遍历(一个个全部访问)
cw(名称[0]) cw(名称[1]) cw(名称[2])......
数组长度 名称.Length
for(int i = 0;i < 名称.Length;i++){
名称[i] //遍历数组的每一个
}
//设计来做循环遍历
foreach(数据类型 变量名 in 数组名){
cw(变量名); //变量就代表数组中每一个元素 不用再写下标了
}
注意事项(面试):
在遍历过程中 此处这个变量 不能修改值
foreach(int i in arr){
i++;//报错,不能修改i的值 i=i+1
cw(x+1);//不会报错 此处只是打印的时候+1,i没有变.
}
5.数据的赋值:
数组[下标]=值; //结合循环,录入数据,一个个录入
在声明的时候初始化了数据
int [] numArray = {1,2,3,4,5}; //声明并赋值数据
6.数组的查找:
bool isFind = false;//标识符
for(int i = 0;i < 数组.Length;i++){
if(数组[i]==找的数据){
//找到了
ifFind=true;
break;
}
}
//循环结束后
if(isFind==false){
//没有找到
}
//做法2
int i=0;//放到循环外面去 才认识
for(;i<数组.Length;i++){
if(数组[i]==找的数据){
//找到了
ifFind=true;
break;
}
}
//循环结束后
if(i==数组.Length){
//没有找到
}
7.新增/修改/删除
a.新增:
指 找到数组中默认值的位置, 放入数据
int i=0;//放到循环外面去 才认识
for(;i<数组.Length;i++){
if(数组[i]==默认值){
//找到了
数组[i]=数据;
break;
}
}
//循环结束后
if(i==数组.Length){
//没有找到 满员了
}
b.修改:
找到数据之后 覆盖
int i=0;//放到循环外面去 才认识
for(;i<数组.Length;i++){
if(数组[i]==要改的数据){
//找到了
数组[i]=新数据;
break;
}
}
//循环结束后
if(i==数组.Length){
//没有找到
}
c.删除:
找到之后,还原成默认值
int i=0;//放到循环外面去 才认识
for(;i<数组.Length;i++){
if(数组[i]==找到的数据){
//找到了
数组[i]=默认值; //假删除
break;
}
}
//循环结束后
if(i==数组.Length){
//没有找到
}
二维数组(了解/使用):
先数行,再数列
理解:一组一堆数组构成的数据类型
语法:
数据类型 [,] 名称 = new 数据类型[行,列];
名称[行序号,列序号] = 值;
操作:
A.二维数组的遍历
for(int i = 0;i<行数;i++)
{
for(int j = 0; j<列数;j++)
{
cw(数组[i,j])
}
}
B:使用二维数组做矩阵操作(求和,反转,对角线) 忽略
C:杨辉三角
程序逻辑:
程序中方法(函数)的作用:
理解:把操作的步骤(某些代码语句)封装起来(打包),之后如果
在想使用这些相同的代码时只需要通过方法的名称调用即可
语法:
访问修饰符 方法修饰符 返回值类型 方法名称(参数1,参数2,...)
{
方法体
//方法中的操作 变量/顺序/选择/循环/数组 程序逻辑中操作
}
访问修饰符:用来指名方面可以在那些地方被调用 public
方法修饰符:用来指名方法会具有某些特别的含义 static
返回值类型:表明方法执行完成后是否有返回的数据 任意数据类型/void
方法的名称:用来调用方法的时候使用的名称 习惯(首字母大写)
参数:调用方法传递数据
方法体:调用方法执行的具体的代码
方法的定义:
方法需要定义在程序主类中!
class 类{
方法的定义语法
}
方法的调用
方法的调用需要在方法里面!
Main 方法中调用才会执行
或在另外一个方法中调用
方法名称();
小技巧:
F12 跳转到方法定义的位置
/// 文档注释 对方法进行注释 使用的时候可以看到该注释(推荐)
方法的分类:
无参数无返回值方法(简单粗暴) 用完就走
带参方法
带返回值方法
带参方法:
定义方法的原则:
方法的功能要越单一越好,一个方法最好只做一件事
避免:在计算,判断这类方法中出现输出输入语句
参数:在调用方法的时候可以给方法里面传递一些数据进去
告诉方法一些值,一些信息
语法:
定义方法(数据类型,参数名1,数据类型,参数名2...)
调用方法(值1,值2,....)按顺序放进去
带返回值的方法:
返回值:在调用的地方可以接收到方法完成之后传出来的数据
方法操作后完成的结果
语法:
定义方法(参数)
{
操作1
操作2
return 返回的数据;//数据和类型要匹配
}
调用方法:
数据类型 变量名 = 定义方法(); //拿到返回的数据,赋值给变量
写方法:
1.需不需要参数,需不需要给方法什么东西
2.方法做完了之后需不需要返回数据 做完之后是否需要返回值
3.怎么做
方法的重载:
变量在同一段代码块{{}中} 不能重复定义相同名字的
多个放在同一个类中定义成相同的名字,但是方法发的参数不能一样
定义:在同一个类中多个方法满足
1.名称相同
2.参数不同
(个数不同,类型不同)
称这些方法之间叫做方法的重载
作用:
如果一堆方法功能是类似的比如(都是打印,都是计算相同的东西)
只是因为参数不同就没必要取不同的名字,让他们重载
特殊参数:
1.不定长参数 params
作用:如果传入的参数个数不确定 使用 params
public static void Test(params int[]array)
{}
调用:test(1)
test(12,34,4)
test(12,34)
//最终都是把你输入的数据 直接放入了 array 数组中
2.out 输出参数
作用:如果一个方法需要返回很多个数据 return
不好用的时候 就使用 out
public static void Test(out int num1,out string name)
{
//计算
//对num1和name赋值
}
调用:
int a;
string n;
Test(out a,out n);//对a和n 赋值 赋num1和name的值
修改控制台的颜色:console.foregroundcolor = consolecolor.green;
console.clear();清除数字
Random rad = new Random();//随机数类
rad.Next(1,100);//1=<x<100 [1,100]
int num = rad.Next();
面向对象
多模仿 重理解
面向对象三大特征(语法):
封装/继承/多态
1.编程式分类:
结构化编程(代表语言:C):解决问题时候通过拆解步骤一步步完成
解决问题:分成很多个步骤,Mian方法一步步写成或者调用方法完成
面向对象编程(代表语言:Java/C#):
解决问题:通过找"人"来帮助你完成问题
2.面向对象编程(oop):
这是一种编程思想,任何语言只要实现了这种编程思想都叫做面向对象编程语言
最主流的编程思想
3.类和对象的概念:
对象:程序中去模拟现实世界的一个称号 万物皆"对象"
特点:实实在在 具体的 实际存在的 东西
组成:
对象身上的信息-->静态特征-->变量-->字段(属性)
对象可以做的事情-->动态特征-->方法
对象 = 静态特征+动态特征
对象 = 属性 + 方法
类:class 类别 种类 分类 一类
把一堆属性或方法相似或者一样的对象聚在一起形成类
抽象的 泛指一类事物 是一类事物统称
类由对象抽象来的 类 = 属性 + 方法
关系:
类是对象的抽象 对象是类的实例化
4.面向对象编码方式:
改变:
之前 Mian方法里面写步骤 适合功能简单 不利于协作
新写法:
项目 需要什么类?设计类
5.类和对象的语法:
1.设计类
访问修饰符 class 类名
{
字段
sting name; //字段
方法
}
建议:
项目 右键 添加 类 (添加了一个新的类文件)
类 = 属性(字段) + 方法
2.使用类:(根据类来创建对象)
创建对象:类的实例化操作
类名 对象名称 = new 类名(); //对象名称任意取
对对象中的属性进赋值操作
对象名称.属性 = 值; //"的"
使用:
cw(对象名称.属性)
注意:
对象中的属性new操作之后 有默认值
通过对象调用其中方法
对象名称.方法名(); //调用其中方法
属性问题:
微软对变量进行了一个单独处理
对象的静态特征-->变量-->把变量默认访问修饰符 private(私有的)
-->默认在外部不能直接访问-->为了放置赋值一些非法的数据
比如:stu.age=-18; //非法数据
解决:
做法1 直接把字段 加上 public (不推荐)
做法2 使用一个方法对字段内部进行赋值 (因为方法中可以加逻辑判断) 推荐做法
对每个字段(变量)都写两个方法GetXxx SetXxx
通过方法对字段进行赋值 或者 访问
简化操作(C#帮你写两个方法):
public 数据类型 变量名称
{
get{}
set{}
}
在 get 和 set 中进行访问控制 数据验证等操作 c#叫属性
Student stu=new Student();
stu.属性 进行操作 //自动调用set方法 或者 get方法
C#完整的类 = 字段 + 属性 + 方法
写属性的两种写法:
1.需要对字段进行验证 进行控制 完整版
快捷键 propfull + tap + tap
private int age;
public int Age
{
get{return age;}
set{
if(value>=0||value<120)
age= value;
}
}
2.不需要做验证 只是需要使用一个属性
prop+ tap+ tap
public int age {get;set;}
2. 封装:
打包 package
设计类:包括 静态特征 动态特征 (属性+方法)
3.对象的初始化操作
初始化:对 对象的属性 进行赋值操作
方法1.
类名 对象 = new 类型;
对象.属性值1=值1;
对象.属性值2=值2;
对象.属性值3=值3;
对象.属性值4=值4;
对象.属性值5=值5;
.....
方法2:
借助对象初始化器 进行初始化 (语法糖)
类名 对象 = new 类名()
{
属性值1=值1,
属性值2=值2,
属性值3=值3,
属性值4=值4,
.....
};
方法3:
借助构造方法完成属性的初始化!!
构造方法:
一种特殊的方法,方法没有返回值(void 都没有),方法必须和类名一致
不能手动调用 在 new 对象的时候系统自动调用
注意:
new 一个对象时一定会去调用构造函数 如果没有系统会自动添加一个
经常会把初始化操作放在构造函数中完成
快捷键:ctor+ tap+ tap
建议:
写构造函数的时候一定要放一个无参构造函数
this 作用:
这个类 构造函数中使用 this 当前类的....
完整类:
字段(经常 省略了 被属性代替了)
属性(静态特征 get/set 方法)
方法(普遍方法 构造方法(数据初始化))
----------------------------------------------------------------------------------------------------------
1.局部变量和全局变量:
局部变量:定义在代码段中的变量(选择/循环结构/方法中),出了代码段就不能使用
全局变量:定义在类中方法外的变量(在同一个类中多个方法之间可以共享)
注意:
在方法中局部变量和全局变量同名时在方法中使用的是局部变量
2.static用法讲解1:
静态的,一静态全静态,如果方法被标识成静态方法比如(Main方法)
那么这个方法中使用的全局变量必须全是静态的
在Main方法中使用全局变量或者直接调用方法 必须加 static
3.形式参数和实际参数
形参:定义方法时使用的参数叫形参
实参:调用方法时实际往里面传入的参数叫实参
形参和实参很多时候名称一样的 但是意义不同,在调用的时候就只是把参数的值
复制给形参,形参拿到方法中去操作
----------------------------------------------------------------------------------------------------------
string 类型
数据类型:值类型/引用类型
特点: string 本质是一个类,使用和操作时当作是值类型在使用
用法:
标准用法:
String 对象名=new String(字符数组);
实际用法:
string str = "abc"; //把字符串类当成值类型在使用
定义:
String/string :没有本质区别,编译器做了一个转换,让和值类型一致
方法/属性:
Length: 获取字符串的长度
Trim(): 去掉字符串前后空格
string.IsNullOrEmpty(字符串) 判断字符串是否为Null或者为""
SubString(起始位置,截取的个数) //字符串的截取
从0开始
字符串[下标]:截取指定位置的那个单字符
IndexOf() //查找指定的字符串第一次出现的位置 找到了返回位置 没有找到返回-1
LsatIndexOf()
Replace() 替换
Remove() 移出指定个数的字符
......
格式化字符串:
string.Format("0:格式化字符串",变量)
C 货币 {0:C2} -->2000 -->¥2.000.00
D 数值 {0:D3} -->5 -->005
补位 {0,3} -->5 --> 5
补位 {0,-3} -->5 -->5
X 16进制 {0:X} -->255 -->FF
f 小数 {0:f} -->1.3 -->1.300
万物皆可 ToString(); --->转换成字符串类型
+"";
string 的问题:
string 是不可变的,每次修改是产生一个新字符串,而不是直接在原来的字符串上修改
问题:频繁修改某个字符串,会产生大量无用的新字符串浪费内存
StringBuilder sb=new StringBuilder ("字符串");
方法:
Insert(位置,插入的字符串) 在指定位置新增一个新字符串
Append("字符串") 在末尾追加一个新字符串