2.1 C#语法的学习(一) && 循环

准备工作

下面让我们以管理员身份运行Visual Studio,新建一个控制台项目,开始C#语法的学习。
以管理员身份运行Visual Studio的问题,请直接搜索关键词:以管理员身份运行 Visual Studio。

可以看到,连官方都有正解的,你没有理由不会!剩下的内容请自行摸索,很简单。
打开Visual Studio后,完成初始化设置,新建一个.net core的控制台,命名为CSharpGrammarLearnConsole。


Visual Studio的使用

在开始学习C#前,最好先对Visual Studio有个初步的了解

在菜单栏的View(视图)中,可以对工具栏、各种窗口的显示、隐藏进行修改,也可以通过拖拽,更改各个窗体的位置。这个根据个人的习惯和使用进行调整即可。

在调试过程中,Visual Studio会发生变化,对于调试来说,比较重要的窗口有LocalsImmediate WindowWatch
如图所示,在代码上打上断点(红点),程序会停在这里,然后可以在Locals窗口查看并修改当前的变量,Immediate Window则可以进行一些即时的运算,Watch则是自定义Locals,可以输入一些自己的关注点,以便多次调试的时候查看变化。
更多详细的教程可以看欢迎使用 Visual Studio IDE
Visual Studio比较重要的技能包括项目管理、调试和远程调试、git版本控制、生成与发布、扩展与更新Visual Studio。其他内容比如代码分析、性能测试等等,个人认为可以按需学习,用到的时候再看都可以。

控制台程序

控制台程序有一个入口,是Program的Main()方法,运行程序后,程序会从Main()方法开始执行。

学习资料 && 学习方式

C#的教学文章、视频,中文的、英文的、官方的、非官方的,很多很多,我在此不赘述,就推荐两个个官方的和一个非官方的吧。
C# 官方文档
.NET 官方文档
菜鸟教程-C# 教程
看了之后是不是觉得有点无从下手,或者不知道可以用它来干什么?很正常,正经的、归纳性的教程就是这样,因为它们更专注于知识点本身,其存在的意义是使大家学会使用XXX,比如学会理解并使用数组、属性、委托和事件。
但它们并不会告诉你数组可以用来完成什么工作,在哪些场景推荐使用它,哪些场景不推荐,它们更多的时候是用来查阅的。比如我很久没有使用委托和事件了,不记得该怎么写了,我也会查一下关键词,随便找一篇文章扫一眼恢复一下记忆—————不必为这种行为感到羞耻,人的大脑不会记住所有事,而语法、语言对于开发者来说也不是非常重要的东西(初学者除外)。计算机思维、设计模式、解决一个问题的思路,这些才是重要的、需要深入理解的东西。
讲C#语法这部分,我想更多的以解决某个问题,促成计算机思维的方式来完成。然后重点讲几个重要的思想:排序穷举递归循环
在具体的语法上面不会做过多赘述,具体的、不明白的地方,看看上面提到的百科全书式的文档,都可以解决,我在用到的时候也会把具体的链接贴出来,请大家放心。希望大家可以和我一起来学习。

第一个问题

求1+2+3+„„+10的和。

数学解法

我们都知道,运算

1+2+3+4+5+6+7+8+9+10=55

但C#是不能写1+2+3+4+5+6+7+8+9+10=?这种等式的,等号左边不能写表达式,右边也不能写?。
所以我们细想一下,实际上我们计算的方式是(不考虑1+9=10,2+8=10这种计算,按顺序执行求和)

1+2=3
3+3=6
6+4=10
......
45+10=55

看明白了么?第一个数字和第二个数字求和,然后求和结果去同第三个数字求和,一直求和到最后一个数字。
理解了如何计算出55这个结果,我们就可以开始写代码了。

C#写法

首先定义一个记录结果的变量

var result=0;

(强烈不建议命名x,y,z blabla,命名一定要有意义!有意义!有意义!重要的事情说三遍——————当然有时候命名会又臭又长,但是还是要好好命名~)
然后我们开始计算

result = result + 1;

这里和数学公式的概念完全不同。
在数学里,这是等式,表示result 等于 result + 1,这个等式并不成立。
而在计算机语言里,这里是赋值,是告诉计算机,计算result + 1的值,并且把值赋给result。所以这个语句执行完毕后,result将等于1。
C#语言中的等式,是双等号==,意义也与数学的等式有所差别,在此不扩展来说。
然后我们继续计算

result = result + 1;
result = result + 2;
result = result + 3;
result = result + 4;
result = result + 5;
result = result + 6;
result = result + 7;
result = result + 8;
result = result + 9;
result = result + 10;

然后输出结果

Console.WriteLine(result);

点击菜单栏下方工具栏中的绿色启动按钮,即可运行程序。

得到结果:

至此,我们完成了把一个问题通过代码来解决的过程。我们做了什么?分析问题-描述算法-把算法写成代码。
不论是什么开发语言,什么问题,都是这样的过程。如果逻辑、算法是不清晰的,代码也是没有办法写的。

或许有人会问,1-10求和,我自己也能算,我为什么还需要学习计算机如何计算?因为计算机不仅可以计算1-10,还可以快速的计算1-100、1-10000、1-99987的求和啊,计算机可以帮助人们快速进行大量的计算,这也是我们学习计算机的目的之一。
下面我们继续分析我们的代码,上述的写法固然可以得到正确的答案,但写的太过冗余,比如如果求和1-100,不是要写100行代码么?这肯定不科学。
累加求和工作内容是固定且重复的,我们可不可以换种轻松的方式来写呢?这时候我们需要一个新的概念,循环

循环

循环的详细描述和用法可以看C# 循环,我们直接开始使用吧~
我们现在转变一下思路:
我们有一个记录循环次数的变量i,
我们需要10次循环,让i从1递增到10(包括10),
则每次计算result = result + i,
最后得到的result就是最终结果。
所以代码是

var result = 0;
for (int i = 1; i <= 10; i++)
{
	result = result + i;
}
Console.WriteLine(result);

是不是简洁很多?而且发现没有,只需要修改10这个数字,我就可以求和1-任意数字的累加和!
那么问题又来了,我想计算1-999、1-8976,应该怎么办呢?我们或许需要交互来帮助我们完成工作。

交互

我们日常的鼠标点击、键盘输入,其实都是交互。比如,鼠标点击了文本框的某一行,光标到达了这一行的某个位置,其实是我们输入了点击这个位置的操作,计算机输出“光标达到这一行”的结果。比如,键盘按下A,文本框输出a,键盘按下Shift+A,文本框输出A,都是计算机根据我们的指令完成工作。
所以同样的,现在我们的工作是,询问程序使用者,求和1-多少,并且输出结果。
在控制台程序中,我们需要用到Console类来帮助我们完成工作。

//询问
Console.WriteLine($"求和1+2+3,,,+n,请输入n的具体数字。");
//得到输入
var n= Console.ReadLine();
//C#是强类型,转换类型
var endNumber = int.Parse(n);
var result = 0;
for (int i = 1; i <= endNumber; i++)
{
	result = result + i;
}
Console.WriteLine(result);

这是一个正确的程序,但并不是一个健壮的程序,比如输入的不是数字,而是其他字符串,就会报错:

对于一个开发者来说,我们不能信任用户的任何输入,我们需要用我们的代码作为武器,去规避、预防、解决这些错误的输入。

判断

在这里,我们可以使用TryParse方法来替换Parse方法。
同时,我们使用了一个if-else的判断条件(C# 判断)。
关于判断更多的内容可以看“2.5 C#语法的学习(五) && 判断”。

var endNumber = 0;
bool isSuccess=int.TryParse(n,out endNumber);
if (isSuccess)
{
	var result = 0;
	for (int i = 1; i <= endNumber; i++)
	{
		result = result + i;
	}
	Console.WriteLine(result);
}
else
{
	Console.WriteLine($"错误的输入{n}");
}

TryParse方法尝试将n转换为int类型,并且赋值给endNumber。isSuccess的结果则是TryParse是否执行成功。
所以,我们使用isSuccess+if-else语句进行判断:如果isSuccess==true,则进行累加求和计算,如果isSuccess!=true,则输出错误提示。
至此,我们学会了处理异常的输入。
但这里似乎还是有一些不方便的地方,比如我如果想多次求和,1-100、1-999,我只能选择:打开一次程序-输入数字-得到结果-关闭程序,然后再次打开程序,重复操作。而且当我录入错误的时候,我还是只能关闭程序,再次打开重新输入。这并不合理。我们期望的效果是,这个程序可以多次计算求和,并且在我们不需要的时候,被我们手动关闭。
我们在求和的时候,用到了循环,来重复的完成一些工作,那么现在我们是不是可以继续使用循环,来解决现在的问题呢?循环整个输入-计算-输出的过程,就可以了~(看到了么,重复性的工作,用循环来解决)

//这里是一个无限循环,一般在开发中不常见,容易出现问题
while (true)
{
	//我们需要循环的方法
}

实现效果:

小结

1.Visual Studio的基本使用
2.等号与双等号在C#中的不同含义
3.循环
4.交互
5.判断
6.程序的正确性与健壮性

延展

1.不能信任用户的输入,在早期有非常严重的体现,就是sql注入。黑客通过系统的漏洞,通过输入不正常的、带有恶意的文本,非法获得系统数据,并对系统进行攻击,让开发者苦不堪言。所以对用户输入的审查,是至关重要的。现在大部分用户输入的校验都在前端、客户端完成,即在没有调用服务的时候,就对输入进行排查,不合法直接不提交数据。
2.while(判断条件)/do-while(判断条件)使用时一定要注意,有时候可能会造成无限循环。
比如,下面这种忘记给number计数。

var number = 0;
while (number < 100)
{
	//完成某件事情

	//忘记写这句话
	//number++;
}

或者更复杂一点,认为判断条件会在某个时间点为false以跳出循环,但某些情况下并不会实现。这种在开发过程中也并不一定会调试出来,可能开发过程中遇不到这种情况。比如尝试下载图片,下载图片完成才能进行下一步操作(显示图片)。正常情况下,下载完成-展示图片,没有问题,但如果遇到网络原因,造成下载图片失败,这种代码就会一直卡在这一步,造成无限循环。
那正常情况下应该怎么处理呢?不知道?我们可以马上知道。
把你的手机wifi、流量都关掉,然后打开淘宝,随便点一件商品,或者打开微信,随便看一篇文章——————这也是一种借鉴的思维,不知道,就去找类似的、你觉得它可能会出现的地方。
然后我们就知道了,它会告诉我们,你的网络崩溃了。那我们的程序是不是应该这样做:
(1)尝试下载图片,并计数尝试下载次数
(2)如果下载成功,展示图片,完成工作
(3)如果下载失败,判断尝试下载次数,
次数没有达到上限100次,则回到(1)重复下载工作
次数达到上限,告知用户下载失败了并指引他后续操作,完成工作
这样的逻辑让这项工作成功、失败的时候,都有了一个“结束”的地方,保证了程序的健壮性。
转换成C#代码如下:
当且仅当尝试下载次数小于100,且下载没有成功时,执行下载操作。

bool isDownloadSuccess = false;
var number = 0;
while (number < 100 && isDownloadSuccess==false)
{
	//下载图片
	//如果下载图片成功,则设置:
	//isDownloadSuccess = true;

	//计数下载次数
	number++;
}

这里还有一个小小的点,下载图片(特别是下载别人家的内容)过于频繁可能会被封掉,被判定是爬虫,所以可以在每次循环的末尾加上一个短时间的、手动的休眠Thread.Sleep(500);

示例代码

上述的大部分代码被上传到CumulativeSum
在Program的Main()方法中取消注释,就可以运行。

题外话

这篇真的是写的,越写越多越写越多,感觉要说的太多了,跟写小论文似的。
因为定位是零基础,所以写的很细,很口水,很简单。后面我也会写得很细,但是相同的问题就会一笔带过,不再重复,所以一定要仔细看哦~

posted @ 2020-02-21 20:47  Lulus  阅读(2248)  评论(0编辑  收藏  举报