Skip to content

Latest commit

 

History

History
251 lines (212 loc) · 8.87 KB

page4.md

File metadata and controls

251 lines (212 loc) · 8.87 KB

上一章

数据与变量

C#程序在运行的过程中,处理数据处理,还有数据存储,现有数据才能进行操作
在上一章的代码中,主函数的参数有个string[] arg这个表示类型为string数组的变量arg
其中这个arg就是一个用于数据存储的容器,你可以往里面读取或者写入数据

数据类型

在存储数据之前,我们需要先知道需要能存什么数据
在C#语言中,默认会提供一些数据类型,这与编程入门里面的数据类型类似但更具体

  • byte/sbyte 1字节整型,其中的sbyte表示有符号
  • ushort/short 2字节整型,其中的ushort表示无符号
  • uint/int 4字节整型,其中的uint表示无符号
  • ulong/long 8字节整型,其中的ulong表示无符号
  • float 4字节浮点型
  • double 8字节浮点型
  • bool 布尔类型,只有true与false
  • char 字符,一般2字节
  • string 字符串,可以储存多个字符组合起来的东西
  • unint/nint 指针,一般8字节

除此之外,还有以下类型

  • 各种类class 是的类也算类型,通常以object为基底
  • 各种记录类型record 与类相似的东西
  • 各种结构体struct 与C语言里面的结构体相似
  • 各类枚举enum
  • 各类元组类型 例如(int, byte)由多种数据类型组合形成的类型
  • 各类 ref 结构类型 表示结构体放在堆栈中,而不是托管堆,可以先不用理解这个
  • 各类数组 类似xxx[]的

例如前面的实例代码中Console其实也是一种类型
字符串一般是类似"123",而字符一般是类似'a'
整数一般为123或者456,当你输入数字后,大部分情况默认会是int类型,如果你需要指定为long类型,你可以输入123L表示这个123long类型
浮点数也是类似,通常输入为double类型,若需要float类型可以输入2.0f
指针类型就是内存指针,一般也是整数,但是储存的内容是内存地址,一般使用的时候会做特殊处理,这个指针与C语言的指针类似

变量与常量

有了数据类型,我们就可以开始将数据按照某个形式存储了,你可以选择存在变量或者常量里面
变量故名思意,就是一个内容可以变化的容器,但变化只能变化值,不能变化类型
常量就是类型跟内容都不能变化的盒子

变量与常量在使用前需要声明,例如

类型 变量名;
类型 变量名=数值;

const 类型 常量名=数值;

有一种特殊的情况下,声明的变量类型可以变换

dynamic 变量名;

使用dynamic作为类型,此时变量里面的值和类型都可以随意变换,且会帮你判断类型并做处理,也就是相当于没有类型了,但是不推荐使用,性能会大幅度下降

在代码中,声明一般是这样写

namespace ConsoleApp1;

internal class Program
{
    static void Main(string[] args)
    {
        int a; //声明一个变量a类型为int
        const int b = 0; //声明一个常量b类型为int,值为0
    }
}

声明的位置可以不在函数内,在类里面也可以

namespace ConsoleApp1;

internal class Program
{
    int a; //声明一个变量a类型为int
    const int b = 0; //声明一个常量b类型为int,值为0

    static void Main(string[] args)
    {
        
    }
}

但是不能在命名空间里面声明

常量在声明的同时,需要给它赋予一个初始值,否则会产生错误

在一些地方,声明变量时有可能为了方便会使用var来表示变量,类型编译器会自动判断

var a = 1; //声明一个类型为int的变量a
var b = true; //声明一个类型为bool的变量b
var c = 1.0f; //声明一个类型为float的变量c
//var d; //错误,无法知道类型

只读修饰符

变量还可以配合readonly来表示这个是一个只读变量,意思是只能赋值一次
在无法赋值常量时,但你又想只能设置一次,可以使用readonly来实现
一般用法

//const List<int> a = [];  //错误,List没有常量的形式存在
readonly List<int> a = []; //声明一个只读变量a类型为List<int>,初始值为0

赋值

常量与变量的赋值,很简单,左边等于右边,左边为变量或者常量,右边为需要给的值

左边 = 右边;
namespace ConsoleApp1;

internal class Program
{
    const int b = 0; //声明一个常量b类型为int,值为0
    int a; //声明一个变量a类型为int

    static void Main(string[] args)
    {
        a = 1; //给变量a赋值1
        //b = 0; //不允许,常量不允许赋值
        a = b; //给变量a赋值常量b的值,也就是0
        a = a; //给变量a赋值a的值,也就是不变
    }
}

注意:变量在使用前,需要先有个值,例如

namespace ConsoleApp1;

internal class Program
{
    int a; //声明一个变量a类型为int
    int b; //声明一个变量b类型为int

    static void Main(string[] args)
    {
        //a = b; //给变量a赋值变量b的值,但是错误,因为b没有默认值
    }
}
namespace ConsoleApp1;

internal class Program
{
    int a; //声明一个变量a类型为int
    int b = 0; //声明一个变量b类型为int,默认值0

    static void Main(string[] args)
    {
        a = b; //给变量a赋值变量b的值,为0
    }
}

变量在赋值的时候,只能赋值同类型,或者低级类型
如果非要赋值,需要使用强制转换操作

int a; //声明一个变量a类型为int
int b = 0; //声明一个变量b类型为int,默认值0
long c = 1; //声明一个变量b类型为long,默认值1
float d; //声明一个变量d类型为float
double e = 3; //声明一个变量e类型为double,默认值3
byte f = 2; //声明一个变量f类型为byte,默认值2

a = b; //给变量a赋值变量b的值,为0
//a = c; //给变量a赋值变量c的值,不允许,因为long长度比int大,不是低级类型
a = f; //给变量a赋值变量f的值,为2
d = b; //给变量d赋值变量b的值,为0
//d = e; //给变量d赋值变量e的值,不允许,因为double长度比float大,不是低级类型

d = (float)e; //给变量d赋值变量e的值,强制转换为d类型

总的来说,就是大的给不了小的,小的可以给大的,若需要给小的,需要进行强制转换,但转换会丢失数据
例如doubel->int会丢失小数部分,只保留整数部分
int->byte会丢失大于byte的部分,也就是范围小了会截取

给变量赋值,可以选择输入的进制

int a = 89; //给变量a赋值10进制的值89
int b = 0x55; //给变量b赋值16进制的值0x55=85
int c = 0b11;  //给变量c赋值2进制的值0b11=3

可空类型

C#中还有一种类型叫做可空类型,意识是里面的数据有可能为null,其声明方式为类型?

int? a = null; //声明一个int可空变量a,初始数据为null
double? b = 1.0; //声明一个double可空变量b,初始数据为1.0
string? c = "123"; //声明一个string可空变量b,初始数据为"123"

使用可空类型一般用于你不确定数据是否存在的情况下,不存在直接给null就可以了
注意:intint?不是一个东西,操作方式会有区别,请使用时需要注意

数组

在某些地方,你需要一个足够大的容器来存储数据,你有两种做法
逐一变量声明

int a1 = 0;
int a2 = 0;
int a3 = 0;
int a4 = 0;
int a5 = 0;
int a6 = 0;
int a7 = 0;
...
int a20 = 0;

或者使用数组

int[] a = new int[20];  //定义一个数组变量,名字为a,类型为int,长度为20

显然是使用数组更方便

数组在定义时,需要决定类型长度
数组里面的内容称为元素,数组的第几个就代表第几个元素
数组一旦定义后,类型与长度均不可以改变,里面的元素会给类型的默认值
关于类型的默认值,可以参考C# 类型的默认值(C# 参考)

定义数组时,可以传递初始值

int[] b = new int[20] = {1, 2, 3, 5, 6};    //定义一个数组变量,名字为b,类型为int,长度为20,且前几个元素

定义时长度,可以是一个变量,但需要保证执行顺序

int a = 20;
int[] b = new int[a];    //定义一个数组变量,名字为b,类型为int,长度为a,因为a为20,所以长度为20

访问数组的内容可以使用变量名[下标]
例如

int[] a = new int[20];
a[0] = 1;                //给数组的第1个赋值1
int b = a[1];            //获取数组的第2个值

访问数组时,下标从0开始,也就是第1个下标为0 当访问超出范围时会报错

int[] a = new int[20];
a[20] = 0; //报错,访问范围超出

下一章