本篇博客的诞生,还要从一次用C#递推写斐波那契数列相关问题开始,引发思考的错误代码如下:
using System;
namespace Work2_1
{
class Program
{
static void Main(string[] args)
{
Console.Write("需要计算的前多少个斐波那契? ");
int n = Console.Read();
Fib(n);
Console.Read();
}
private static void Fib(int n)
{
int a = 1, b = 1, c = 0, i;
Console.Write("{0}\t{1}\t", a, b); //每8个字符输出一个数
for (i = 3; i <= n; i++)
{
c = a + b;
Console.Write("{0}\t", c);
if (i % 5 == 0) //要求每行输出5个斐波那契数
{
Console.WriteLine();
}
a = b; b = c;
}
}
}
}
初学C#时照猫画虎,为了挽留控制台窗口驻足一会,自然而然地遵循课本的经验,像往常一样在Main()方法最后写上Console.Read(),遗憾的是它还是闪退了。
于是,在最后一句代码处加个断点,强行扣留一下,观察发现它还溢出了。
寻思了一下,又瞅瞅代码,发现了和之前敲的例题代码不一样的地方:
int n = Console.Read();
啊,难怪不让我多看两眼控制台,传的数据类型对不上呀,C#与C进行文本输入是不同的:
C#:使用Cosole.ReadLine()接收的是键入的字符串,需要配合Parse()方法,转换成需要使用的数据类型。比如:
string s = Console.ReadLine();
int a = int.Parse(s); //之后才可以使用希望得到的a中的数据。
C:使用库函数scanf(),自动将键入的数据转化成与变量对应的数据类型。比如:
int a;
scanf("%d", &a); //后续直接使用a中的数据即可。
补充:同样是面向对象编程的Java代码也和C#差不多复杂,需要使用其他方法转换类型,比如:
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
经过一番思考,稍稍一改就可以产出正确代码,得到正确的输出:
static void Main(string[] args)
{
Console.Write("需要计算的前多少个斐波那契? ");
string sline = Console.ReadLine();
int n = int.Parse(sline);
Fib(n);
Console.Read();
}

PS: 为什么 int n = Console.Read(); 编译不报错呢?
先来看方法的声明 public static int Read ();
返回值类型与变量 n 的类型一致,自然不会编译出错。
该方法的作用是从标准输入流读取下一个字符,如果当前没有更多的字符可供读取,则为-1。
当 Read 你键入输入字符时,方法会阻止其返回; 当按下键时,该方法将终止 Enter 。
按 Enter 会将与平台相关的行终止序列附加到输入 (例如,Windows 会将回车换行符序列附加) 。
【C#官方文档】https://docs.microsoft.com/zh-cn/dotnet/api/system.console.read?view=netcore-3.1.
看过一波官方文档后,发现ReadKey()方法才是为暂停看控制台窗口量身定制的,Read()只是恰好效果相同。
ReadKey()方法的最常见用途之一 ,是在用户按下某个键(就像C语言程序运行完成后提示的“请按任意键继续…”)时暂停程序执行,然后应用终止或显示其他信息窗口。
[题外话]:
char可以被int兼容,就隐式转换了,至于转换成什么,目前不太清楚,搜索一番后发现有人说这样读写是错乱了很多东西,输出的是不可预知的乱码,里面包含有各种控制符,难怪最后的ReadLine()不生效。
推荐参考如下博客思考一下char和int类型转换问题:
https://bbs.csdn.net/topics/391886193.
https://blog.csdn.net/alex4chan/article/details/5771620?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase.
continue…