zl程序教程

您现在的位置是:首页 >  其他

当前栏目

C#基础到入门(一篇就够了)(二)

2023-03-14 22:54:39 时间

🍺分支语句

⌨条件运算符


  • 条件运算符(三元运算符)
    • 条件表达式 ? 结果a : 结果b
  • if的第一种形式
if(条件表达式){
    语句1;
} 
  • if的第二种形式
if (条件表达式)
{
  语句1;
}
else
{
  语句2;
} 
  • if的第三种形式
if (条件表达式1)
{
  语句1;
}
else if (条件表达式2)
{
  语句2;
}
else
{
  语句3;
} 
  • Switch
    • 如果case 冒号后面没有任何语句,可以不加break;
    • Switch()括号中是可以允许添加浮点型变量的,但不推荐
      • 浮点型是有误差的
      • 浮点型一般不做等于的判断
        • 企业面试题:有一个浮点数,判断该浮点数是不是等于5

⌨循环语句

  • while循环
while (条件表达式)
{
  //循环内容
} 
  • break关键词
    • 跳出本循环(通常与if连用)
  • continue关键词
    • 结束本次循环(continue后面的代码不再执行),进入下次循环。(通常与if连用)

练习:👍👍👍👍👍👍

从键盘输入一个算数运算式,使用if语句实现正确的算数运算,并输出运算结果

例如:

请输入第一个数字:4

请输入运算符:+

请输入第一个数字:2

计算结果为:6

输入一个生日日期,输出其星座.

白羊座:3.21-4.19,金牛座:4.20-5.20,双子座:5.21-6.21,巨蟹座:6.22-7.22

狮子座:7.23-8.22,处女座:8.23-9.22,天秤座:9.23-10.23,天蝎座:10.24-11.22

射手座:11.23-12.21,魔羯座:12.22-1.19,水瓶座:1.20-2.18,双鱼座:2.19-3.20

例如:

请输入月:12

请输入日:21

您是射手座

🐖数组

🉑🉑一维数组的初始化


动态初始化

数据类型[] 数组名=new 数据类型[数组长度];

此时数组中每一个元素都是为默认值

int的默认值0

float的默认值0

bool的默认值false

char的默认值‘’,表示空字符

string的默认值""

数据类型[] 数组名=new 数据类型[数组长度]{元素1,元素2…};

数据类型[] 数组名=new 数据类型[]{元素1,元素2…};

静态初始化

数据类型[] 数组名={元素1,元素2…};

🉑数组的访问

从0开始计数

array.Length是数组的长度,只读的。

访问数组时,切记下标所对应的数组元素是存在的

如果不存在,就会引发数组越界异常

🉑引用数据类型

数据类型

值类型(存储在栈内存)

栈内存里存的是具体的值

前面学习过的值类型

int、float、bool、char

引用类型(存储在堆内存)

栈内存里存的是地址(堆内存的地址)

目前学习过的引用类型

string(特例)、数组

🉑遍历数组

遍历数组:

访问数组中的每一个元素

int[] array = { 1,8,4,8,7,45,456,789,78,76};

for (int i = 0; i < array.Length; i++)
{
 Console.WriteLine(i + ":" + array[i]);
}

image.png

👂👂二维数组、结构体、枚举

👂👂冒泡排序


  • 思想:
    • 当前数组元素与后面的数字元素进行对比,如果前大后小,则进行交换
    • 每轮可以确定一个最大值在数组的末位,几轮之后即可完成排序
    • 冒泡排序当然也可以从大到小排序,那样则前小后大进行交互
      代码:
for (int i = 0; i < array.Length; i++)
{
    //立个flag,表示判断过程中是否发生了交换
    bool IsjiaoHuan= false;

    for (int j = 0; j < array.Length - i - 1; j++)
    {
        if (array[j] > array[j + 1])
        {
            //说明交换了
            IsjiaoHuan= true;
            //交换
            int temp = array[j];
            array[j] = array[j + 1];
            array[j + 1] = temp;
        }
    }

    if(!IsjiaoHuan)
    {
        //说明已经排好序了,后面的轮次就没有必要了
        break;
    }

    for (int m = 0; m < array.Length; m++)
    {
        Console.Write(array[m] + "	");
    }

    Console.WriteLine();

}

Console.WriteLine("排序结束");

for (int m = 0; m < array.Length; m++)
{
    Console.Write(array[m] + "	");
}

image.png

👂👂二维数组的定义

  • 数据类型[,] 数组名;

👂int[,] array;

二维数组的初始化

  • 动态初始化
    • 数据类型[,] 数组名 = new 数据类型[第一维长度,第二维长度];

👂int[,] arr= new int[50,3];数据类型[,]

数组名 = new 数据类型[,]{数组值};

👂int[,] arr= new int[,]{{1,0,1},{3,0,5}};


静态初始化

数据类型[,] 数组名 = {数组值};

👂int[,] arr= {{1,0,1},{3,0,5}};


二维数组的元素访问

数组名[第一维下标,第二维下标]

👂 arr[3,2]


谨防数组越界


  • 二维数组的长度
    • 总长度(二维数组的元素个数)
      • array.Length
    • 第一维的长度
      • array.GetLength(0)
    • 第二维的长度
      • array.GetLength(1)
  • 二维数组的遍历
for (int i = 0; i < heroData.GetLength(0); i++)
{
   for (int j = 0; j < heroData.GetLength(1); j++)
   {
       Console.Write(heroData[i,j] + "	");
   }
   //换行
   Console.WriteLine();
}
  • foreach迭代遍历
    • 迭代遍历是只读的,不能修改
//foreach性能消耗要大一点,所以能用for的尽量用for
foreach (var item in number)
{
    Console.WriteLine(item);
    //迭代遍历是只读的,不能写入
    //item = 1;
}

👂👂枚举类型

  • 枚举类型是一个自定义类型
  • 枚举类型是一个值类型
  • 枚举类型的创建
//装备类型
enum EquipType
{
    Helmet = 100,//头盔
    BodyArmor = 200,//防弹衣
    Knapsack,//背包
    Knife
}
  • 枚举类型变量的定义与使用
//定义一个枚举类型的变量
EquipType myEquip = EquipType.Knapsack;
EquipType yourEquip = EquipType.Knapsack;
//判断枚举变量
if(myEquip == EquipType.BodyArmor) { }
switch (myEquip)
{
    case EquipType.BodyArmor:
        break;
    case EquipType.Helmet:
        break;
    case EquipType.Knife:
        break;
        //case EquipType.
    default:
        break;
}
//枚举类型和整型之间的转换
//枚举类型可以强制转换为整型
int num = (int)myEquip;
Console.WriteLine(num);
//整型可以强制转换为枚举类型
myEquip = (EquipType)200;
Console.WriteLine(myEquip);
//既然枚举可以用整数去表示
Console.WriteLine(myEquip+2);

👂👂结构体类型

  • 结构体类型是自定义类型
  • 结构体类型是值类型
  • 结构体类型的创建
//学生类型
struct Student
{
    public string name;
    public char sex;
    public int age;
}
  • 结构体类型变量声明及字段赋值
//定义一个学生变量
Student xiaoming;
//学生结构内变量赋值
xiaoming.name = "xiaoming";
xiaoming.age = 16;
xiaoming.sex = 'M';
  • 结构体的构造函数
    • 结构体默认的构造函数,开发者不能创建默认构造(即无参构造)
public Student()
{
    
}
  • 结构体的自定义构造函数,方便创建结构体变量时给字段赋值
//自定义构造函数
public Student(string n,char s,int a)
{
    //作用:快速给结构体字段赋初值
    //而且必须给每一个字段都赋初值
    name = n;
    sex = s;
    age = a;
}
  • 初始化结构体变量
//有了自定义的构造函数后,如何新建结构体变量
Student xiaogang = new Student("xiaogang",'M',18);

👂👂结构体练习题

eg:

#region 结构体、枚举
//创建英雄装备结构体,包含名称,攻击力加成,法术强度加成,血量加成,装备类型
enum EquipType
{
   AD,
   AP,
   HP,
   Other
}
//英雄装备
struct HeroEquip
{
   public string name;
   public float adAddition;
   public float apAddition;
   public float hpAddition;
   public EquipType equipType;

   public HeroEquip(string name, float adBuff, float apBuff, float hpBuff, EquipType equipType)
   {
       //给所有字段赋初值
       this.name = name;
       adAddition = adBuff;
       apAddition = apBuff;
       hpAddition = hpBuff;
       this.equipType = equipType;
   }
}

#endregion
#region 结构体、枚举练习

//有5个装备保存在结构体数组当中,编程找出血量加成最高者
//对装备数组按照攻击力加成排序并使装备按照攻击力加成升序进行信息打印

HeroEquip wjzr = new HeroEquip(
   "无尽之刃", 100, 0, 50, EquipType.AD);
HeroEquip yxj = new HeroEquip(
   "饮血剑", 80, 0, 20, EquipType.AD);
HeroEquip ktkj = new HeroEquip(
   "狂徒铠甲", 0, 0, 150, EquipType.AD);
HeroEquip dmj = new HeroEquip(
   "兰德里的折磨", 20, 100, 0, EquipType.AD);


//声明结构体数组存储这些装备
HeroEquip[] heroEquips = { wjzr, yxj, ktkj, dmj };

//设置初始血量最大值
float maxHPBuff = heroEquips[0].hpAddition;
//设置初始血量最大值的装备名称
string maxHPEquipName = heroEquips[0].name;

HeroEquip maxHPEquip = heroEquips[0];

       //找血量最大
       for (int i = 0; i<heroEquips.Length; i++)
       {
           if (maxHPBuff<heroEquips[i].hpAddition)
           {
               //更新最大值
               maxHPBuff = heroEquips[i].hpAddition;
               //更新最大值的装备名称
               maxHPEquipName = heroEquips[i].name;
           }

           //如果声明结构体
           if (maxHPEquip.hpAddition<heroEquips[i].hpAddition)
           {
               maxHPEquip = heroEquips[i];
           }
       }

       Console.WriteLine("装备列表中,血量加成最高的装备是
"
            + maxHPEquip.name + ",最大值是"
            + maxHPEquip.hpAddition);
Console.Read();
#endregion

image.png

🍺🍺🍺面向对象

⌨⌨面向过程


  • 重点关心解决问题的步骤
  • 优点:
    • 可以很清晰的看明白问题解决的步骤
    • 代码的行数要少一些,性能消耗低一些
  • 缺点:
    • 不易维护、不易拓展、不易复用

⌨⌨面向对象

  • 重点关心解决问题过程中参与的对象有哪些,分别有哪些特性和行为
  • 优点:
    • 易维护、易拓展、易复用
  • 缺点:
    • 代码是分散的,行数会多一些
    • 性能消耗要高一些

⌨⌨类和对象

  • 创建一个类
[访问修饰符] Class 类名//大驼峰命名法
  • 创建一个类的对象
类名 对象名;
  • 类的类型是一个引用类的型
  • 类的类型是一个自定义类型
  • 一个对象在创建后,需要进行实例化(初始化)才能使用
类名 对象名 = new 类名();

原理 : 对象在进行new操作后,才分配了内存。

5.png

  • 字段
    • 描述类的特性
    • 要使用小驼峰命名法命名
    • 可以有初值
  • 帮助注释
    • 帮助注释也是一种注释
    • 谁可以添加帮助注释
      • 方法
      • 字段
      • 属性
    • 帮助注释的优点
      • 在使用类、方法、字段、属性的时候,可以在提示框中显示帮助注释的内容

6.png

  • this关键词
    • 表示当前对象
    • 如果没有重名冲突,可以不写(省去)
  • Random随机数类
    • 第一步,先创建一个随机数对象
Random random = new Random();
  • 第二步,调用随机数对象的Next方法
    • 调用时要传入两个参数,即随机数字的取值范围
      - 如传入的是4和8,则随机数字范围为4至7,不包含8(这个方法就是这么写的)
      - 即取值范围为左闭右开,即[min,max)
      - 方法返回的结果即随机到的数字,需要用整型变量去接收
int num = random.Next(0,array.Length);
  • 方法
    • 方法是描述一个类的某个特定行为
    • 一个方法尽量就完成一件小的事情
      • 如果要完成一件大事
        • 先定义一些方法,完成这个大事拆分出来的小事
        • 最后在按照流程,在大事方法中调用这些小事的方法
    • 方法要用大驼峰命名法命名
    • 方法的创建
 [访问修饰符] 返回值类型 方法名(参数列表)
 {
   //方法体
   //实现方法功能
   return 结果;//最终别忘了返回方法结果,结果类型需与返回值类型保持一致
 }
  • 方法的调用
对象名.方法名(参数列表);//无论有无参数,小括号都要存在
  • return关键词
    • 返回结果
    • 终止方法,即return后面的语句不会执行

image.png

🍺🍺属性、方法参数

⌨⌨属性


属性命名方式使用大驼峰

在属性访问器内写代码,切记一点

Get访问器内不要写读取该属性的语句

Set访问器内不要写写入该属性的语句

否则,会出现递归循环,死循环

属性简写:public string Name { get; set; } = “先生”;

image.png

⌨⌨引用参数ref

  • 添加了ref关键词的参数
    • 传递的就不是值了
    • 而是地址
      • 而如果没有赋初值,是没有地址的
      • 所以ref参数一定是个变量
      • 所以ref参数的实参一定是赋过初值
  • 所以ref一般加在值类型参数的前面
  • 使用应用参数,无论是形参还是实参前面都要加ref关键词

7.png

⌨⌨输出参数out

  • 添加了out关键词的参数
    • 参数就成了一个输出的通道
    • 离开方法之前形参必须赋值
    • 实参必须是一个变量
    • 传递的实参一般是值类型
  • 使用输出参数,无论是形参还是实参前面都要加out关键词

8.png