c#-语法知识

105 阅读13分钟

变量

1.折叠代码

// 引用命名空间
using System;
// 命名空间
namespace lesson2_变量
{
    // 类
    class Program
    {
        // 函数
        static void Main(string[] args)
        {
            // 在打印台上打印出 Hello world
            Console.WriteLine("变量");

            // 折叠代码
            // 作用 编程时逻辑更加清晰
            // 由 #region   #endregion 配对出现的
            // 作用 将中间的代码折叠起来 避免代码太凌乱 MyRegion描述
            #region MyRegion

            #endregion
        }

    }

}

效果如下图

image.png

2.变量

变量 可以变化的容器 变量 就是用来存储各种不同类型数值的 一个容器

不同的 变量类型 可以存储不同类型的值

变量申明固定写法

变量类型 变量名 = 初始值;

//1.有符号的整形变量 是能存储 一定范围 正负数包括0的变量类型
// sbyte -128~127
sbyte sb = 1;
//潜在知识点 通过+来进行拼接打印
Console.WriteLine("sbyte变量sb中存储的值是:" + sb);
// int  -21亿~21亿多
int i = 2;
// short -32768~32767之间的数
short s = 3;
// long -9百万兆~9百万兆之间的数
long l = 4;

//2.无符号的整形变量 是能存储 一定范围 0和正数的变量类型
// byte 0~255
byte b = 1;
// uint 0~42亿多的一个范围
uint ui = 2;
// ushort 0~65535之间的一个数
ushort us = 3;
// ulong 0~18百万兆之间的数
ulong ul = 4;


//3.浮点数(小数)
//float 存储7/8位有效数字 根据编译器不同 有效数字也可能不一样 四舍五入
//有效数字 是从左到右从非0数开始算有效数字的
//之所以要在后面加f 是因为c#中 申明的小数 默认是double的类型 加f 是告诉系统 它是float类型
float f = 1.01234567890f;
Console.WriteLine(f);
//double 存储15~17位有效数字 抛弃的数字 会四舍五入
double d = 0.12345678901234567890123456789;
Console.WriteLine(d);
//decimal 存储27~28位的有效数字 不建议使用
decimal de = 0.123456789012345678901234567890m;
Console.WriteLine(de);

//4.特殊类型
//bool true false 表示真假的数据类型  真假类型
bool bo = true;
bool bo2 = false;
Console.WriteLine(bo + "_" + bo2);

//char 是用来存储单个字符的变量类型 字符类型
char c = '唐';
Console.WriteLine(c);

//string 是字符串类型 用来存储多个字符的 没有上限
string str = "的骄傲了肯定就发生123123sdafjkasdkfjaskldjfAKKSAJD";
Console.WriteLine(str);


int x = 1000;
Console.WriteLine(x);
//变量的使用和修改 不能不中生有 必须要先声明才能用
x = 900;
Console.WriteLine(x);

3.变量的本质

变量的存储空间(内存中)

1byte = 8bit

1MB = 1024byte

1GB = 1024MB

1TB = 1024GB

 // 通过sizeof方法 可以获取变量类型所占的内存空间(单位:字节)
 //有符号
 int sbyteSize = sizeof(sbyte);
 Console.WriteLine("sbyte 所占的字节数为:" + sbyteSize);
 int intSize = sizeof(int);
 Console.WriteLine("int 所占的字节数为:" + intSize);
 int shortSize = sizeof(short);
 Console.WriteLine("short 所占的字节数为:" + shortSize);
 int longSize = sizeof(long);
 Console.WriteLine("long 所占的字节数为:" + longSize);
 Console.WriteLine("******************************************");
 //无符号
 int byteSize = sizeof(byte);
 Console.WriteLine("byte 所占的字节数为:" + byteSize);
 int uintSize = sizeof(uint);
 Console.WriteLine("uint 所占的字节数为:" + uintSize);
 int ushortSize = sizeof(ushort);
 Console.WriteLine("ushort 所占的字节数为:" + ushortSize);
 int ulongSize = sizeof(ulong);
 Console.WriteLine("ulong 所占的字节数为:" + ulongSize);
 Console.WriteLine("******************************************");
 //浮点数
 int floatSize = sizeof(float);
 Console.WriteLine("float 所占的字节数为:" + floatSize);
 int doubleSize = sizeof(double);
 Console.WriteLine("double 所占的字节数为:" + doubleSize);
 int decimalSize = sizeof(decimal);
 Console.WriteLine("decimal 所占的字节数为:" + decimalSize);
 Console.WriteLine("******************************************");
 //特殊类型
 int boolSize = sizeof(bool);
 Console.WriteLine("bool 所占的字节数为:" + boolSize);
 int charSize = sizeof(char);
 Console.WriteLine("char 所占的字节数为:" + charSize);
 
 //sizeof是不能够得到string类型所占的内存大小的
 //因为字符串长度是可变的 不定 
 //int stringSize = sizeof(string);

变量的本质

变量的本质是2进制——>计算机中所有数据的本质都是二进制 是一堆0和1

为什么是2进制?

数据传递只能通过电信号,只有开和关两种状态。所以就用0和1来表示这两种状态

计算机中的存储单位最小为bit(位),他只能表示0和1两个数字

1bit 就是1个数 要不是0要不是1

为了方便数据表示

出现一个叫byte(字节)的单位,它是由8个bit组成的存储单位。

所以我们一般说一个字节为8位

1byte = 0000 0000

2进制和10进制的对比

2进制和10进制之间的相互转换

4.变量的命名规范

必须遵守的规则

1.不能重名

2.不能以数字开头

3.不能使用程序关键字命名

4.不能有特殊符号(下划线除外)

常用的命名规范

驼峰命名法——首字母小写,之后单词首字母大写(变量

帕斯卡命名法——所有单词首字母都大写(函数、类)

潜在知识点——C#中对大小写是敏感的 是区分的

    //驼峰命名法——首字母小写,之后单词首字母大写(变量)
    string myName = "aa";
    string yourName = "你的名字";
    string yourMotherName = "";

    //帕斯卡命名法——所有单词首字母都大写(函数、类)
    string MyName = "dskafj";

    //潜在知识点——C#中对大小写是敏感的 是区分的

5.常量

常量的申明

关键字 const

固定写法: const 变量类型 变量名 = 初始值;

示例

  const int i = 20;

常量的特点

1.必须初始化

2.不能被修改

示例

  string name;
  //之后可以来修改
  name = "123";
  name = "345";


  //作用:申明一些常用不变的变量

  //PI 3.1415926
  const float PI = 3.1415926f;

  Console.WriteLine(PI);

6.转义字符

转义字符的使用

什么是转义字符?

它是字符串的一部分 用来表示一些特殊含义的字符

比如:在字符串中表现 单引号 引号 空行等等

固定写法

固定写法 \字符

不同的 \和字符的组合 表示不同的含义

示例

 //常用转义字符
 // 单引号 \'
 string str = "\'哈哈哈\'";
 Console.WriteLine(str);

 // 双引号 \"
 str = "\"哈哈哈\"";
 Console.WriteLine(str);

 // 换行 \n
 str = "1231231\n23123123123";
 Console.WriteLine(str);

 // 斜杠 \\  计算机文件路径 是要用到\符号的
 str = "哈\\哈哈";
 Console.WriteLine(str);

 //不常用转义字符(了解)
 // 制表符(空一个tab键)  \t
 str = "哈\t哈哈";
 Console.WriteLine(str);

 // 光标退格  \b
 str = "123\b123";
 Console.WriteLine(str);

 // 空字符 \0
 str = "1234\0123";
 Console.WriteLine(str);

 // 警报音  \a
 str = "\a";
 Console.WriteLine(str);


 Console.WriteLine("1231231231\n123123213\a\t123123");

取消转义字符

示例

 string str2 = @"哈哈\哈哈";
 Console.WriteLine(str2);

 Console.WriteLine(@"\n\\");

输出结果

image.png

7.类型转换

什么是类型转换?

类型转换 就是不同变量类型之间的相互转换

隐式转换

隐式转换的基本规则——>不同类型之间自动转换

大范围装小范围

相同大类型之间的转换
 #region  相同大类型之间的转换

 //有符号  long——>int——>short——>sbyte
 long l = 1;
 int i = 1;
 short s = 1;
 sbyte sb = 1;
 //隐式转换 int隐式转换成了long
 //可以用大范围 装小范围的 类型 (隐式转换)
 l = i;
 //不能够用小范围的类型去装在大范围的类型
 //i = l;
 l = i;
 l = s;
 l = sb;
 i = s;
 s = sb;

 //无符号 ulong——>uint——>ushort——>byte
 ulong ul = 1;
 uint ui = 1;
 ushort us = 1;
 byte b = 1;

 ul = ui;
 ul = us;
 ul = b;
 ui = us;
 ui = b;
 us = b;

 //浮点数  decimal    double——>float
 decimal de = 1.1m;
 double d = 1.1;
 float f = 1.1f;
 //decimal这个类型 没有办法用隐式转换的形式 去存储 double和float
 //de = d;
 //de = f;
 //float 是可以隐式转换成 double
 d = f;

 //特殊类型  bool char string
 // 他们之间 不存在隐式转换
 bool bo = true;
 char c = 'A';
 string str = "123123";

 #endregion

不同大类型之间的转换
 #region 不同大类型之间的转换

 #region 无符号和有符号之间
 //无符号 不能装负数的
 byte b2 = 1; //0~255
 ushort us2 = 1;
 uint ui2 = 1;
 ulong ul2 = 1;
 //有符号
 sbyte sb2 = 1;
 short s2 = 1;
 int i2 = 1;
 long l2 = 1;

 //无符号装有符号 
 // 有符号的变量 是不能够 隐式转换成 无符号的
 //b2 = sb2;
 //us2 = sb2;
 //ul2 = sb2;

 //有符号装无符号 
 // 有符号变量 是可以 装 无符号变量的 前提是 范围一定要是涵盖的 存在隐式转换
 //i2 = ui2;//因为 有符号的变量 可能会超过 这个无符号变量的范围
 i2 = b2;// 因为 有符号的变量 不管是多少 都在 无符号变量的范围内

 #endregion

 #region 浮点数和整数(有、无符号)之间
 //浮点数装整数 整形转为浮点数 是存在隐式转换的
 float f2 = 1.1f;
 double d2 = 1.1;
 decimal de2 = 1.1m;

 //浮点数 是可以装载任何类型的 整数的
 f2 = l2;
 f2 = i2;
 f2 = s2;
 f2 = sb2;

 f2 = ul2;
 f2 = ui2;
 f2 = us2;
 f2 = b2;

 f2 = 10000000000000000000;
 Console.WriteLine(f2);

 //decimal 不能隐式存储 float和double
 //但是它可以隐式的存储整形
 de = l2;
 de = ul2;

 // double ——> float ——> 所有整形(无符号、有符号)
 // decimal ——> 所有整形(无符号、有符号)

 //整数装浮点数 整数是不能隐式存储 浮点数  因为 整数 不能存小数
 //i2 = f2;

 #endregion

 #region 特殊类型和其它类型之间

 //bool bool没有办法和其它类型 相互隐式转换
 bool bo2 = true;
 char c2 = 'A';
 string str2 = "1231";
 //bo2 = i2;
 //bo2 = ui2;
 //bo2 = f2;

 //i2 = bo2;
 //ui2 = bo2;
 //f2 = bo2;

 //bo2 = c2;
 //c2 = bo2;
 //bo2 = str2;
 //str2 = bo2;

 //char char 没有办法隐式的存储 其它类型的变量
 //c2 = i2;
 //c2 = f2;
 //c2 = ui2;
 //c2 = str2;

 //char类型 可以隐式的转换成 整形和浮点型
 //char隐式转换成 数值类型是 
 //对应的数字 其实是一个 ASCII码 
 // 计算机里面存储 2进制
 // 字符 中文 英文 标点符号 在计算机中都是一个数字
 // 一个字符 对应一个数字 ASCII码就是一种对应关系
 i2 = c2;
 Console.WriteLine(i2);
 f2 = c2;
 Console.WriteLine(f2);
 ui2 = c2;
 Console.WriteLine(ui2);

 //str2 = c2;

 //string 类型 无法和其它类型进行隐式转换
 //i2 = str2;
 //ui2 = str2;
 //f2 = str2;

 #endregion

 #endregion
总结

高精度(大范围)装低精度(小范围)

double ——> float ——> 整数(无符号、有符号)——>char

decimal ——> 整数(无符号、有符号)——>char

string 和 bool 不参与隐式转换规则的

8.枚举

什么是枚举

被命名的整形常量的集合,一般用它来表示 状态 类型 等等

申明枚举语法
枚举名 以E或者E_开头 作为我们的命名规范
enum E_自定义枚举名
{
    自定义枚举项名字, //枚举中包裹的 整形常量  第一个默认值是0 下面会依次累加
    自定义枚举项名字1,//1
    自定义枚举项名字2,//2
}

enum E_自定义枚举名
{
    自定义枚举项名字 = 5, //第一个枚举项的默认值 变成5了 
    自定义枚举项名字1,// 6
    自定义枚举项名字2 = 100,
    自定义枚举项名字3,//101
    自定义枚举项名字4,//102
}
在哪里申明枚举

1.namespace语句块中(常用)

2.class语句块中 struct语句块中

注意:枚举不能在函数语句块中申明!!!

枚举如何使用

申明枚举变量

自定义的枚举类型 变量名 = 默认值;(自定义的枚举类型.枚举项)

如下列代码所示

  E_PlayerType playerType = E_PlayerType.Other;

  if( playerType == E_PlayerType.Main )
  {
      Console.WriteLine("主玩家逻辑");
  }
  else if(playerType == E_PlayerType.Other)
  {
      Console.WriteLine("其它玩家逻辑");
  }

  //枚举和switch是天生一对
  E_MonsterType monsterType = E_MonsterType.Boss;
  switch (monsterType)
  {
      case E_MonsterType.Normal:
          //Console.WriteLine("普通怪物逻辑");
          //break;
      case E_MonsterType.Boss:
          Console.WriteLine("Boss逻辑");
          break;
      default:
          break;
  }

枚举的类型转换

如以下代码所示:

 // 1.枚举和int互转
 int i = (int)playerType;
 Console.WriteLine(i);
 //int 转枚举
 playerType = 0;

 // 2.枚举和string相互转换
 string str = playerType.ToString();
 Console.WriteLine(str);

 //把string转成枚举呢
 //Parse后 第一个参数 :你要转为的是哪个 枚举类型 第二个参数:用于转换的对应枚举项的字符串
 //转换完毕后 是一个通用的类型 我们需要用括号强转成我们想要的目标枚举类型
 playerType = (E_PlayerType)Enum.Parse(typeof(E_PlayerType), "Other");
 Console.WriteLine(playerType);

数组

基本概念

数组是存储一组相同类型数据的集合

数组分为 一维、多维、交错数组

数组的申明
            // 变量类型[] 数组名;//只是申明了一个数组 但是并没有开房
            // 变量类型 可以是我们学过的 或者 没学过的所有变量类型
            int[] arr1;

            // 变量类型[] 数组名 = new 变量类型[数组的长度];
            int[] arr2 = new int[5]; //这种方式 相当于开了5个房间 但是房间里面的int值 默认为0

            // 变量类型[] 数组名 = new 变量类型[数组的长度]{内容1,内容2,内容3,.......};
            int[] arr3 = new int[5] { 1, 2, 3, 4, 5 };

            // 变量类型[] 数组名 = new 变量类型[]{内容1,内容2,内容3,.......};
            int[] arr4 = new int[] { 1,2,3,4,5,6,7,8,9}; //后面的内容就决定了 数组的长度 “房间数”

            // 变量类型[] 数组名 = {内容1,内容2,内容3,.......};
            int[] arr5 = { 1,3,4,5,6};//后面的内容就决定了 数组的长度 “房间数”


            bool[] arr6 = { true, false };

数组的的使用

如下代码所示

            int[] array = { 1, 2, 3, 4, 5 };
            //1.数组的长度
            // 数组变量名.Length
            Console.WriteLine(array.Length);

            //2.获取数组中的元素
            //数组中的下标和索引 他们是从0开始的
            //通过 索引下标去 获得数组中某一个元素的值时
            //一定注意!!!!!!!!
            //不能越界  数组的房间号 范围 是 0 ~ Length-1
            Console.WriteLine(array[0]);
            Console.WriteLine(array[2]);
            Console.WriteLine(array[4]);

            //3.修改数组中的元素
            array[0] = 99;
            Console.WriteLine(array[0]);

            //4.遍历数组 通过循环 快速获取数组中的每一个元素
            Console.WriteLine("**********************");
            for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
            Console.WriteLine("**********************");
            //5.增加数组的元素
            // 数组初始化以后 是不能够 直接添加新的元素的
            int[] array2 = new int[6];
            //搬家
            for (int i = 0; i < array.Length; i++)
            {
                array2[i] = array[i];
            }
            array = array2;
            for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
            array[5] = 999;
            Console.WriteLine("**********************");
            //6.删除数组的元素
            // 数组初始化以后 是不能够 直接删除元素的
            // 搬家的原理
            int[] array3 = new int[5];
            //搬家
            for (int i = 0; i < array3.Length; i++)
            {
                array3[i] = array[i];
            }
            array = array3;
            Console.WriteLine(array.Length);

            //7.查找数组中的元素
            // 99 2 3 4 5 
            // 要查找 3这个元素在哪个位置
            // 只有通过遍历才能确定 数组中 是否存储了一个目标元素
            int a = 3;

            for (int i = 0; i < array.Length; i++)
            {
                if( a == array[i] )
                {
                    Console.WriteLine("和a相等的元素在{0}索引位置", i);
                    break;
                }
            }

异常捕获

日常写代码的过程中我们总会遇到程序因为报错而卡死的情况,但是我们通过对异常捕获的学习 可以避免当代码报错时 造成程序卡死的情况

基本语法

如下代码所示

  //必备部分 
  try 
  {
      //希望进行异常捕获的代码块
      //放到try中 
      //如果try中的代码 报错了 不会让程序卡死
  }
  catch
  {
      //如果出错了 会执行 catch中的代码 来捕获异常
      //catch(Exception e) 具体报错跟踪 通过e得到 具体的错误信息
  }
  //可选部分
  finally
  {
      //最后执行的代码 不管有没有出错 都会执行其中的代码
      //目前 大家可以不用写
  }
  //注意:异常捕获代码基本结构中 不需要加; 在里面去写代码逻辑时  每一句代码才加;