初步

学习C#自然推荐使用宇宙最强IDE Visual Studio,初学下载社区版,安装过程中,将除了移动开发之外的带有C#和.Net字样的选项都勾上。

安装完成后,打开VS->创建新项目->C#控制台应用->下一步->项目名称、位置随便写->下一步->框架选.Net6.0->点击创建,然后就会看到我们的第一个CSharp程序。

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

代码的可读性是非常强的,Console表示控制台,WriteLine就是写下一行,合起来就是在命令行中写一行话,这行话就是Hello World!。

C#中,通过//进行单行注释/**/进行多行注释。每行代码要以分号;结尾!!

按下F5就可以执行这段程序了,弹出命令行,内容为

Hello, World!

E:\Documents\00\1116\CSharp\MyFirstCS\bin\Debug\net6.0\MyFirstCS.exe (进程 17312)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

这里额外说一段,对于.Net5.0以前的版本,需要在这个语句外面套一层Main函数,Main函数外面套一层Class,Class外面再套一层namespace。

数学计算和函数

常用的数学计算可通过运算符来实现,比如加减乘除,就是+-*\,此外还有%表示求余,例如

Console.WriteLine(5%3);

命令行中出现2。

除了Lisp风格的语言之外,绝大多数编程语言对四则混合运算的支持都有良好的可读性,比如2+3*5这种式子,其实是无需详述的。

但四则混合运算其实并不能完全满足我们的需求,最起码很多情况下需要用到平方,为了实现这个功能,就需要自定义函数

double square(double x)
{
    return x * x;
}
Console.WriteLine(square(3.5));

F5执行之后,命令行输出了12.25。

接下来,将上面的表达式对应到y=f(x)=x2这样的函数表达式中

d1 f(d2 x)
{
    return y;
}

也就是说,类比数学中的概念,square为函数名,x为自变量,y为因变量。而在编程领域,一般把x叫做输入参数,y则叫做返回值。

而d1和d2所对应的double,则为输入变量和输出变量的数据类型。

变量和数据类型

从数学的角度,可以非常简单粗暴地理解数据类型,即数据类型有两类,一类是小数,一类是整数。对于希望速成的初学者来说,整数用int表示,小数用double表示,当然编程中一般把小数叫做浮点数。

这时就有一个尖锐的问题,"Hello World"又是个啥?

好吧你赢了,那就再加一种数据类型,就是字符串。而且字符串和数值还有区别,小数和整数尽管类型不同,但总可以互相计算的,比如小数和整数相加,最后得到的是个整数;但小数和字符串相加,最后应该没法得到值。

也就是说,四则混合运算对字符串不适用。

你可能不信,于是写出了这行代码

Console.WriteLine("Hello" + "World");

好吧你又赢了,+只在高中数学中表示加法,在编程语言中只是一个代码,既可以将其定义为加法,也可以将其定义为字符串拼接。

有了数据类型,就可以定义变量

double square(double x){
    return x * x;
}
double a = 1.5;
int b = 2;
Console.WriteLine(square(a)+b);

最后命令行输出4.25,square(a)是对浮点数做平方,然后输出了浮点数,而b是整型,根据输出结果可以直到,浮点型和整型相加,最后的结果仍然是浮点型。

布尔类型和判断

数值计算和解析计算的区别在于,后者是无限的,而前者是有限的。网上经常说π又算到了多少多少位,就讲出了这个区别。π 显然是无穷多位的,但计算机只能表现出有限的位数,这种位数的限制,使得整型和浮点型内部产生了分 裂。

众所周知,计算机操作的是二进制的逻辑电路,用32位二进制,可以表示的最大整数就是232=4294967296,要是还想考虑一下0,那就再要减一,要是再考虑负数,就要再减半。

C#中提供了多种位数的整型和浮点型,其中整型又包括有符号和无符号两种,所谓有符号,就是有正有负;无符号就是0和正整数。比如double就是64位浮点型;int是32位有符号整型;uint是32位无符号整型。

当数据位数降到1位时,一位的二进制就只剩下两个值0和1,仿佛是一个开关,于是量变引起了质变,布尔类型诞生了。

这个时候,0 00和1 11被赋予了非常重要的现实意义,用于表示无或有,以及错和对,即false和true。

有了对错,就可以判断,在几乎所有编程语言中,都用if表示判断

void trueOrFalse(bool c){
    if(c){
        Console.WriteLine("你是对的");
    }
    else{
        Console.WriteLine("我是错的");
    }
}
trueOrFalse(true);

运行之后,输出你是对的。

抛开if不谈,这个函数也和之前定义的不太一样,这个函数没有返回值,所以其输出的数据类型为void。

大多数人接触if时的学习案例往往是这个

void bigOrlittle(int a, int b)
{
    if (a > b)
    {
        Console.WriteLine($"{a}>{b}");
    }
    else if (a < b)
    {
        Console.WriteLine($"{a}<{b}");
    }
    else
    {
        Console.WriteLine($"{a}={b}");
    }

}
bigOrlittle(3, 5);
//输出为 3<5

这个案例给出了完整的判断语句,if...else if...else,中间的else if可以为无穷多个。据说有一款游戏中,堆了一个19亿次判断的屎山,被坊间传为笑谈。

其中,<是也是一种运算符,其输入为两个数值,输出为布尔型变量。如果左边的小于右边的,就输出true,否则就输出false。这类运算符被统称为条件运算符,包括全等判断==,不等判断!=以及>,<,>=,<=。

数组和for循环

前文提到,除了数值之外,字符串是另外一种数据类型,这两种类型之间并不能直接运算。而且前文又提到,数值类型和二进制的位数是息息相关的,32位整型能表示的最大数值不超过232

但字符串似乎并没有这种限制,只要计算机内存扛得住,似乎可以在双引号中写入任意长度的字符串。这种奇怪的特性表明,字符串并不是一种单纯的数据类型,而是由字符组成的串。

所谓字符,就是诸如'a','b','c'这样单个的字母或者文字,它们和数值类型都要受到二进制位数的限制。C#中的char类型由两个字节组成,也就是16位二进制,最多可以涵盖65536个单字。而字符串,就是由这一个个字符拼接而成。

推此及彼,数值类型也应该有类似的串的结构,此即数组,其声明方式如下

int[] arr = new int[5];
Console.WriteLine(arr);
// System.Int32[]

int[]表示整型数组,new表示创建一个数组的实例,后面int[5]表似乎这个数组的长度为5。最后调用Console.WriteLine来打印arr,结果并没有输出数组的内容。

先不考虑数组是否支持用WriteLine,arr在创建出来之后,其实并没有为其赋值,所以非要输出,输出为空也是符合逻辑的。

数组赋值的方法也很便捷,arr[0]=1表示将arr中的第0个值赋为1。千万要注意,C#中,索引序号是从0开始的。

接下来又出现了一个严重的问题,如果要创建一个有1000个元素的数组,那给数组初始化不得写1000行?要是按行数算工资的话老板不得亏死?

所以接下来就引入另一个概念,for循环,如下

int[] arr = new int[5];
for (int i = 0; i < 5; i = i+1)
{
    arr[i] = i * i;
}

在(int i=0; i<5; i=i+1)中,int i声明了一个变量,i=0表示这个变量从0开始,i=i+1表示每次循环,i都变成i+1,i<5表示只有在i<5的情况下才执行循环。

由于i=i+1这种写法过于繁琐,C#提供了自增运算符i++,再意义上与i=i+1等价。

花括号中是循环体,对数组arr逐个进行赋值。唯一比较可惜的是,Console.WriteLine并不能直接把数组中的内容打印出来,为了打印数组中的内容,还要再写个循环

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(arr[i])
}

当然,对于数组操作,这里其实推荐这种写法

foreach (var e in arr)
{
    Console.WriteLine(e);
}

foreach表示遍历数组中的所有元素,再(var e in arr)中,var表示自动判定数组内元素的数据类型,e则为遍历到的arr中的元素创建一个临时的变量。这样就把arr中所有的元素打印出来了。

0
1
4
9
16

当然,圈子兜了这么远,主要目的并不是初始化数组,而是为了讲述for循环,因为数组初始化有更加便捷的方式

int[] arr = {0,1,4,9,16}

while循环与跳出

其实有了for循环就已经可以解决几乎所有循环问题了,但从逻辑上来说,for循环并不存粹,里面加入了大量私货。毕竟对循环而言,其实只需要一个循环条件就可以了,符合这个条件就循环,不符合就跳出,while就是干这个的,其使用方法与if十分相似

double a = 1.5
while(a*a<100){
    a++;
    Console.WriteLine(a);
}

但while中没有else,也就是说,只能判断一个条件,如果有多个跳出条件,可以用break。

while(a*a<100){
    a++;
    if(a>5){
        //当a>5时,跳出循环
        break;
    }
    Console.WriteLine(a);
}

另一种情况是,如果并不想把所有a都打印出来,则可以通过continue来跳过某次循环,下面打印出平方小于100的所有奇数

a = 0
while(a*a<100){
    a++;
    if(a%2==0){
        //当a>5时,跳出循环
        continue;
    }
    Console.WriteLine(a);
}
原文地址:https://tinycool.blog.csdn.net/article/details/127883251

相关文章: