文章目录
- 简介
- 隐式显式转换
- if
- switch
- 循环
- 随机数
- 方法
- do while
- static
- 递归
- 数组
- foreach
- var推断类型,父类
- 二维数组,交错数组
- 当方法参数类型确定,个数不确定时
- 数据类型
- 类型分类
- 快捷方式
- 函数参数:引用、输出参数
- 装箱,拆箱
- string
- 储存地址
- 枚举类型
- 养成代码规范
- 类
- 数组扩容
- 集合
- 字典
- 类得继承
- 共享数据
- 获取二维数组不同方向的坐标
- 结构
简介
C# 又称C shape。用Visual studio开发
推荐字体:
文本编译器-所有语言,设置显示行号
一个项目,打开,是打开sln文件
using System;
//using 引入命名空间,如果没有using,需要写成System.Console.WriteLine
//经常使用该类的时候,需要using.多个文件有相同名字的类,用Using的命名空间区分
//using的作用:对类进行逻辑上的划分,避免重名
//命名空间-类-方法
//定义命名空间【类的住址】
namespace Day01
{
class Program
{
static void Main(string[] args)
{
//代码对齐ctrl+K+F,左手按住ctrl不放,右手先按K,再按F
//注释ctrl+K+C
//取消注释ctrl+K+U
Console.Title = "俺的第一个程序";
Console.WriteLine("你好,世界!");
//从控制台输入文本
string input = Console.ReadLine();
Console.WriteLine(input);
Console.ReadLine();//让程序在本行暂停
}
}
}
无符号数是8个位置全储存数据,有符号数就是7个位置储存数据。
char 加单引号,string加双引号。char c1=‘1’ string s1=“1” bool b=false b=1>2
变量:数字,字母,下划线,组成。不能是关键字如Int,不能数字开头。
建议:以小写字母开头,多个单词,第一个单词小写开头,其他首字母大写如:className,strAge
局部变量在使用前不许赋值。
bool b1=result==0.1f,先比较result是否等于0.1f,结果为bool型给b1
调试的步骤
1.在可能出错的行,加断点,在左侧的灰色地带
2.按F5。启动调试
3.按F11,逐语句执行。在鼠标放变量上变量上,会显示值
4.按shift+F5停止调试
字符串的拼接,不方便分析。
console.write(“枪的名字是:”+gunName+“弹夹容量”+ammoCapacity);
推荐用占位符:{3},代表第3个变量。
string str=string.Format(“枪的名字为:{0},容量为:{1}”,gunName,ammoCapacity);
非整形float n2=1.0f,要加后缀
double n2=1.0不用加后缀
没加后缀会有提示。
看异常信息:1异常原因2位置
在控制台输出代码的占位符:Console.WriteLine(“金额:{0}”,10);
标注数字字符串格式化:{数字:C}
Console.WriteLine(“金额:{0:c}”,10);//货币,输出 金额:¥10.00
数字,不足2位时用0来填充
Console.WriteLine(“{0:d2}”,5);//05
Console.WriteLine(“{0:d2}”,15);//15
Console.WriteLine(“{0:f1}”,1.26);//1.3,根据指定精度,四舍五入显示
Console.WriteLine(“{0:p1}”,0.1);//10.0%,以百分数显示,小数点后位数是p后面的数字
//转义符,改变字符原始含义 "
Console.WriteLine(“我爱"unity”")输出:我爱”unity“
char c=‘’’ //输出: ’
char c2=‘\0’ // 空字符’’
Console.WriteLine(“你好,\r\n我是隔壁的\t老宋。”)//\r\n换行,\t是tab键。输出:你好,
我是隔壁的 老宋。
//源代码(.cs的文本文件)
bool r3=n1%20,怎么看, r3=(n1%20)
取整数的个位:int r=n1%10,取个位
逻辑运算符:&& || !
console.WriteLine(n++)//结果自增以前
console.WriteLine(++n)//结果自增以后
三元
string stro1=1>2?“OK”:“NO”
string 转换成其他数据类型,待转的数据必须像该数据类型
string strNumber=“18”
int num01=int.Parse(strNumber);//18
float num02=float.Parse(strNumber);//18.0
任意类型转换为string类型
int num=18;
string str=num.ToString();
获取每一位,方案一:
//取string的某一位
string str=“1234”
char c1=str[0];//1
个位:int re=num%10;
十位:int re=num/10%10;
百位:int re=num/100%10;
如果求每一位的和,可以直接写成
个位:int re=num%10;
十位:int re+=num/10%10;
百位:int re+=num/100%10;
字符转字符串:
char c1=‘e’;
sting s1=c1.ToString();
获取每一位,方案二:
隐式显式转换
隐式转换(由小范围到大范围)
byte b3=100;
int i3=b3;
但是反过来会报错:int i3=100;byte b3=i3;得用显示转换,又可能有精度得丢失(由大范围到小范围)byte b3=(byte)i3
因为byte是8位,int是32位
byte b=1;
b+=3;//不会报错,因为快捷运算符,不做自动类型提升
b=b+3;会报错,用显式转换
byte b=250;
b+=6;//结果为0,因为byte存0~255
//b+=7;//结果为1
if
if(sex==“男”)
{
Console.WriteLine(“您好,先生!”);
}else{
}
if(***)
b++;//受if控制
console.write;//不受if控制,而且会隔开之后的else if。所以if后有多个语句,用{}框起来
switch
switch(op)
{
case “+”:
re++;
break;
case"-":
re–;
break;
case “1”:
case “2”:
case “3”:
re=1;
break;//op为1,2,3都会执行
default:
re=0;
break;
}
不一定一定要用break,也可以用return返回方法,顺便也退出了switch
循环
for(初始化;循环条件;增减变量){
}
for(int i=0;i<5;i++){//满足i<5才会进入循环体内
}
i++先执行i再++;
++i先加,再执行;
i++和++i对下一跳指令都没区别,是加了之后的效果。
for(int i=0;i<5;){//满足i<5才会进入循环体内
//语句
i++;
}
for(int i=3; ;i++)//循环体能否执行,取决于中间,中间为空,相当于true,进入死循环。
{
}
for(int i=0;i<5;){
//语句
continue;//跳过本次循环,本次循环的后面全部语句不执行,直接进入下一次循环
i++;
}
while(条件){//满足条件才可进入循环,适用于只知道判断条件,不知道循环次数的情况
}
不建议用goto 语句
while(true){
if(条件)
break;
}
随机数
Random random=new Random();//创建一个随机数工具,本句放在方法外面,类里面
int num=random.Next(1,101);//产生一个随机数,本句放在方法里面
方法
没有返回值的方法也可以些return;但是return后面不能跟数据。
return的作用:1返回值,2退出方法。return执行后,它后面的代码不会执行。
void表示无返回值,可以不写return.
函数定义时的参数是形参,函数调用时的参数是实参。两者的类型,顺序,个数要意义对应。
string str=“我叫戎狄!”
str=str.Insert(4,“吗”);在第4个位置插入0我1叫2戎3狄4,我叫戎狄吗!
int index=str.IndexOf(“我”);返回0.查找指定字符在字符串中的索引。
int index=str.IndexOf(“戎”);返回2.查找指定字符在字符串中的索引。
Remove(2)删除位置2及以后的字符
Replace(‘我’,‘你’);用你来替代我
StartsWith(“我叫”)从开始比较是否一致,返回bool
如何定义方法
上面的方法不好,因为方法应该只做一件事,上面有获取数据,数据处理。而且上面的方法只能用在控制台,要尽可能使方法走在哪都能用,能复用。应该:
Console.Write写不换行
Console.WriteLine写并换行
在方法上敲三个/,注释
\n换行
\t相当于敲了一个Tab键
1代码要能复用,用调方法的方式,防止代码修改的工作量
2防止代码量太大,层次不清晰
方法名称写成一个,但是参数不一样。可以在不同情况下调用,使用者只需要记住一个函数名字。调用时,会通过参数去区分。即:方法的重载:方法名称相同,参数列表不同,作用:在不同条件下,解决同一类问题,让调用者仅仅记忆一个方法
do while
do
{
}while(count<5)
条件放后面,会先执行一下循环体,再判定
static
在C#程序中,没有全局变量的概念
静态变量必须使用类名来引用,而不能使用类的实例,因为,静态变量不属于任何实例,而是共有的
静态方法与静态变量一样,不属于任何特定的实例,属于类全体成员共有,由类名来调用。但要注意以下几点:
静态方法只能访问类的静态成员,不能访问类的非静态成员;
非静态方法可以访问类的静态成员,也可以访问类的非静态成员;
静态方法不能使用实例来调用,只能使用类名来调用。
递归
方法内部又调用自身的过程
核心思想:将问题转移给范围缩小的子问题
范围不能再缩小的情况为方法结束的判定
一层一层得执行GetFactorial等到有返回了,就一层一层得相乘。
使用时,尽量用循环,能不用递归就不用递归。缺点:性能较差,每次执行都要开辟空间,内存消耗比较大。
一般考试喜欢考递归,原因,优点:因为它可以让复杂问题,简单化。
注意:方法内部调用自身,要防止堆栈溢出,即需要有判定条件return;
数组
首先放的是数据类型的默认值。
下标从0开始。
int型,容量6,下标最多是5.
for循环满足条件才++,可以把i++放在循环体内,而不是for语句那
初始化+赋值
声明+初始化+赋值
new float[3]{“a”,“b”}会报错,因为前面已经说了有3个元素,后面也得有3个元素,前后一致。
new float[]{“a”,“b”}可以省略【】中的数字
sort是从小到大排序,如果需要从大到小排序,再调用一下反转reverse
判断数组中是否存在这个元素,如果不存在,IndexOf会返回-1
IndexOf会返回第一个数据的下标,当有多个相同数据,时,如果想返回最后一个数据的下标用:
foreach
用此循环更简单。从头到尾读取数据。如果要从尾到头,或从中间开始,或跳着读取,foreach就不行,得用for循环。
foreach得优点:使用简单
缺点:如果要从尾到头,或从中间开始,或跳着读取,foreach就不行,得用for循环。
var推断类型,父类
//适用性:数据类型名称较长,用var使代码简洁
不适合:全篇都var,代码可读性不好
foreach(var item in array){
}
可以声明父类类型,赋值子类对象
万类之祖:object
返回值是数组的方法:
二维数组,交错数组
交错数组:
遍历交错数组的所有元素
或者
当方法参数类型确定,个数不确定时
1用数组
2 加params ,参数数组
对方法内部而言就是个普通数组,
对于方法外部(调用者),可以传递数组,可以传递一些数据类型相同的变量(传的是一大堆数,但方法看到的是一个数组),甚至可以不传递参数(方法看到的是个0个元素的数组)
作用:简化调用者,调用方法的代码。
数据类型
类型分类
arr2和arr是指向的同一个内存地址,改变arr会同时改变arr2所以方法参数是数组的,需要改变数组时,可以不用写返回值。
快捷方式
F12 跳转到方法或类的定义。
调用方法时,只写一个(,会提示写什么参数。不要一下子写个()
函数参数:引用、输出参数
引用参数,作用改数据
按值传递,引用传递的函数参数,传递之前前,必须赋值,不然会报错。
但是函数的输出参数,传递之前可以不赋值。但是函数内部必须给输出参数赋值
装箱,拆箱
避免装箱
不要写成
但是现在电脑的硬件性能很牛,拆装箱,该用就用,这点性能消耗很小,没问题。但是面试的时候会考。
string
字符串拼接不能这样干,会产生垃圾
字符串拼接,用,创建一个可变字符串。
每次修改都在同一个,内存空间内。
new StringBuilder()的框里,尽量写准确,有几个字符的空间。不然如果有更多的字符拼接,也能成功拼接上,但是会浪费更多的内存空间。
频繁对字符串操作(增加,替换,移除),需要用StringBuilder,如果只操作一次,就可以只用string。
储存地址
枚举类型
=0,=1可以不写
枚举能多选的操作:条件二的[Flags]是可写可不写。
养成代码规范
类首字母大写,变量首字母小写。
类
比较便捷的set和get方法
真实开发时,不用写get和set方法,写个属性就行。如属性Name。如果类的外部不需要访问这个字段,就不需要写属性Name.
字段首字母小写,属性首字母大写。
如果有这种错误:
函数的重载,变量名相同,参数不同。
数组扩容
因为数组初始化必须指定大小,且不可改变。调用数组数据必须指定下标。这两个弊端,所以引入
集合
数组只在容量确定,每次引用可以有确定下标时才用。不然就用集合。
字典
想快速得查找某一个数据,用字典效率更高
类得继承
子类能用父类得东西。父类只能用父类。父类要用子类,要强制转一下。protect修饰的变量,只能本家族使用,即本类和他得子类可以用。
父转子还能用:
共享数据
每个对象都操作的同一个数据。
比如可以用于类创建了多少个对象。
获取二维数组不同方向的坐标
二维数组存储坐标,比如要获得a点左下角的坐标。创建一个derection类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Day08
{
/// <summary>
/// 方向
/// </summary>
struct Direction
{
private int x;
public int X
{
get
{ return x; }
set
{ x = value; }
}
public int Y { get; set; }
//结构体一定提供无参数构造函数
//所以不能写无参数构造函数
//public Direction()
//{ }
public Direction(int x, int y):this()
{//在构造函数中,必须先初始化所有字段 (可以使用无参数构造函数进行初始化)
this.X = x;
this.Y = y;
}
public static Direction Up
{
get
{
return new Direction(-1,0);
}
}
public static Direction Down
{
get
{
return new Direction(1, 0);
}
}
public static Direction Left
{
get
{
return new Direction(0, -1);
}
}
public static Direction Right
{
get
{
return new Direction(0, 1);
}
}
}
}
调用:Direction dir = Direction.Right;