C--编程零基础入门指南-三-

61 阅读27分钟

C# 编程零基础入门指南(三)

原文:C# Programming for Absolute Beginners

协议:CC BY-NC-SA 4.0

十四、基本工具

你已经完成了这本书的两部分。在接下来的两部分中,您将学习更复杂的主题,例如处理条件和循环。为了让你正确理解这些主题,在这一章中,我将介绍一些对你的编程有很大帮助的工具。

智能感知

您知道我将介绍的第一个工具:Visual Studio IntelliSense。每当您开始键入任何内容时,Visual Studio 都会立即为您提供完成文本的选项。当您选择其中一个选项时,开发环境会在工具提示中向您显示关于该选项的更多细节——该选项做什么,它需要什么参数,等等。

我在这一章中介绍智能感知,因为它经常被初级程序员使用。我建议您习惯于使用智能感知来完成您键入的几乎每个单词。你将省去大量的错别字。

探索可能性

使用智能感知也是探索当代计算平台提供的所有可能性的一种方式。

在过去,你必须研究手册或书籍中的可能性。他们中的一些人有足够的能力回答一个程序员几乎所有的问题。然而,今天有如此多的可能性,甚至一本 1000 页的书也不能把它们全部展示出来。

你还需要书(肯定是这本!)为您提供可靠而系统的指导,使您能够理解其中的原理,但您可能希望探索那里没有提到的进一步的可能性。智能感知是一个工具,可以向你展示其中的许多。

例子

你在寻找操纵文本的可能性吗?创建一个string类型的变量,并输入其名称后跟一个点(见图 14-1 )。

img/458464_2_En_14_Fig1_HTML.jpg

图 14-1

输入变量名和点号

当你直接输入string后跟一个点时,你可以找到更多的可能性(见图 14-2 )。

img/458464_2_En_14_Fig2_HTML.jpg

图 14-2

输入数据类型和点号

你在寻找可以和约会对象一起做的事情吗?输入DateTime变量,然后输入一个点(见图 14-3 )。

img/458464_2_En_14_Fig3_HTML.jpg

图 14-3

输入日期时间和一个点

像文本一样,你可以输入DateTime和一个点,得到一些有用的提示(见图 14-4 )。

img/458464_2_En_14_Fig4_HTML.jpg

图 14-4

从智能感知中获得一些提示

注意

使用列表底部的图标可以缩小 IntelliSense 为您提供的可能性列表。如果您只想查看属性、方法等等,请单击适当的图标。

快捷键

有时,当您执行某项操作时,智能感知会消失。在这种情况下,您可能会发现 Ctrl+J 或其他键盘快捷键很有用。要获得他们的列表,在 Visual Studio 的菜单栏中,选择编辑➤智能感知➤列表成员(见图 14-5 )。

img/458464_2_En_14_Fig5_HTML.jpg

图 14-5

列表成员的快捷键

文件

智能感知可以给你很多提示。它还可以显示您搜索的功能的基本用法。但是,您可以找到所有详细信息的地方是在线文档。

docs.microsoft.com

位于http:// docs.microsoft.com的网站是寻找任何关于 C# 和其他微软技术的最佳起点(见图 14-6 )。在页面上,单击“文档”,然后直接转到“C#”。

img/458464_2_En_14_Fig6_HTML.jpg

图 14-6

Microsoft 文档

搜索

您可以使用提供的链接使用文档网站。然而,更常见的是,你要搜索特定的东西。例如,在搜索字段中输入控制台类别并按回车键(参见图 14-7 )。

img/458464_2_En_14_Fig7_HTML.jpg

图 14-7

正在搜索“控制台类”

你感兴趣的链接往往是第一个返回的(见图 14-8 )。

img/458464_2_En_14_Fig8_HTML.jpg

图 14-8

查看“控制台类”的文档

特定类页面

点击正确的链接后,你会找到关于某个特定类的所有东西,比如本例中的Console

当我开始熟悉一些我还不知道的类时,我通常会寻找“通用操作”和“备注”部分,它们涵盖了关于类使用的基本信息和进一步细节的入口点(见图 14-9 和 14-10 )。

img/458464_2_En_14_Fig10_HTML.jpg

图 14-10

在备注部分获取更多详细信息

img/458464_2_En_14_Fig9_HTML.jpg

图 14-9

在通用操作部分获取介绍性信息

普通搜索

作为本节文档的总结,请注意,您也可以在 Microsoft 文档网站之外执行搜索。只需使用您最喜欢的网络浏览器进行搜索。

然而,与文档网站搜索相反,普通搜索更频繁地显示不相关的结果。为了弥补这一点,您可以使用编程语言名称来细化您的查询,例如在您最喜欢的 web 浏览器的搜索字段中输入控制台类 C#

调试工具

除了 IntelliSense 和文档之外,您还会发现其他一些有用的工具。具体来说,你可以使用调试工具,可以说,这些工具允许你查看计算机内部。您可以使用它们来查看计算机如何执行单个命令,内存中存储了哪些值,等等。

这些就是你现在要研究的工具。最初,开发它们是为了方便程序调试,换句话说,是为了查找和消除错误。然而,作为说明性工具,它们可能更有助于您理解各种编程结构。

项目

最好在实践中尝试所有的工具,所以请从第八章开始在 Visual Studio 中打开“处理不正确输入”项目。程序将两个数相加,并使用try-catch处理可能的输入错误。

单步执行代码

计算机工作速度如此之快,以至于不可能以千兆赫的速度跟上它。这就是为什么逐步执行代码通常是有帮助的,这迫使计算机根据你的命令一次执行一条语句。

转到您打开的“处理不正确的输入”项目,并使用 F10 键启动它,而不是通常的 F5。当然,选择调试➤单步调试菜单也是一样的(见图 14-11 )。

img/458464_2_En_14_Fig11_HTML.jpg

图 14-11

使用 F10 键启动程序

现在,每当您按下 F10 时,就会一次执行一个单独的程序语句。一直以来,使用黄色箭头和黄色背景,开发环境表示将在下一步中执行的语句。

现在只要玩踏脚。尝试用户输入正确数据的情况以及错误输入的情况。IDE 将向您展示try-catch或其他任何东西是如何工作的。这可以让你亲眼看到程序是如何运行的。

终止步进

当你找到你要找的东西时,你不必一步一步地通过程序到最后一条语句。还有其他选择:

  • 使用 F5 键(或调试➤继续),你可以继续正常的程序执行(没有步进)。

  • 使用 Shift+F5 键(或调试➤停止调试),可以终止程序执行。

断点

我已经介绍了在您已经过了您感兴趣的点之后,如果您不想逐句通过您的代码,该怎么办。还有一种情况。说你不想在到达感兴趣的地方之前做任何事情。在这种情况下,您可以使用一个断点

单击计算机要停止的语句并按 F9 键(或者,右键单击并选择断点➤插入断点)。断点已被放置的事实用暗红色背景和在行首的暗红色项目符号表示(见图 14-12 )。

img/458464_2_En_14_Fig12_HTML.jpg

图 14-12

插入的断点

使用断点

如果您的程序仍在运行,请使用 Shift+F5 组合键终止它。现在以常规方式启动程序,换句话说,使用 F5 键。它会正常运行,到达断点就停止。Visual Studio 在程序的窗口前弹出。

之后,您可以逐句通过代码或只是看一些东西,并使用 F5 键来进一步运行您的程序,直到它的结尾或直到下一个断点。

移除断点

要删除不再需要的断点,请在特定行上再次按 F9,或者右键单击并从上下文菜单中选择断点➤删除断点。

内存检查

每当程序挂起时(从断点、单步执行等),您可以检查程序可用的内存,并浏览各个变量的值。

为了便于内存检查,Visual Studio 在其窗口底部显示了“汽车”、“局部变量”和“监视”窗格。如果没有这些窗格,您可以使用调试➤窗口菜单来显示它们。

“自动”和“局部变量”窗格自动选择要显示的变量,而“监视”窗格则根据您希望看到的内容手动填充。您可以在窗格中输入特定变量的名称,或者您可以在代码中右键单击变量并从上下文菜单中选择添加监视(参见图 14-13 )。

img/458464_2_En_14_Fig13_HTML.jpg

图 14-13

选择添加观察

所选变量的当前值出现在监视窗口中(参见图 14-14 )。

img/458464_2_En_14_Fig14_HTML.jpg

图 14-14

使用监视窗口

C# 交互式

我在这里提到的最后一个工具可以帮助你在交互模式下学习 C# 语句。

这是什么?

到目前为止,你总是不得不写一个有几个语句的程序,然后启动它来看它的运行。交互模式允许您输入单个 C# 语句并立即运行它们。通过这种方式,您可以更快地探索一些 C# 特性。

如何推出?

您可以通过选择查看➤其他窗口➤ C# 交互来启动交互模式(参见图 14-15 )。您甚至不需要创建/打开项目。

img/458464_2_En_14_Fig15_HTML.jpg

图 14-15

切换到交互模式

图 14-16 显示了一个交互会话的例子——我声明了一个数字变量,增加了 10,并显示了它的值。

img/458464_2_En_14_Fig16_HTML.jpg

图 14-16

示例交互式会话

笔记

请注意以下几点:

  • 如果需要输入多行语句,可以用 Shift+enter 来终止行,而不是简单的 Enter。

  • 使用#help显示关于如何使用交互模式的简明信息。

摘要

本章向您介绍了可以在编程中使用的工具,包括 IntelliSense、文档、调试工具和交互模式。

当您在 Visual Studio 编辑器中键入时,IntelliSense 会显示可用可能性和相应工具提示的列表。你已经知道如何使用它了。在这里,我介绍了 IntelliSense 作为探索巨大的 C# 世界的一种方式。例如,如果您想要操作文本,并且您不知道相应的方法是如何调用的,那么您可以在一个string变量后面加上一个点,然后浏览各种可能性。您还可以在类型名称后面加上一个点,以获得更多的可能性。

您了解了 Microsoft 文档网站,该网站包含所有 Microsoft 编程技术的宝贵信息,包括 C# 语言和。NET 平台。您通常在此网站上执行全文搜索。

在这一章中,我揭示了一些调试工具,它们可以让你看到“计算机内部”您可以观察各个语句是如何执行的,检查变量值,等等。具体来说,您学习了如何单步执行代码、设置断点和检查内存。

交互模式是一种快速输入 C# 语句并查看它们的功能的方式。这是一个探索新特性的好工具。

十五、条件入门

到目前为止,一个程序的语句总是从开始执行到结束,而不管其他任何事情,只是在轮到它们的时候执行。在这一章中,整个新世界将开始展现自己,因为你将学习程序语句的条件执行。这意味着您将根据是否满足某个条件来处理可能执行也可能不执行的语句。

密码输入

您的第一个带条件的程序将评估一个密码。用户可能被允许也可能不被允许进入系统,这取决于他们是否输入了正确的密码。

工作

您将编写一个程序,提示用户输入密码,然后评估输入的密码是否正确。为了简单起见,正确的密码将直接在代码中指定(见图 15-1 和 15-2 )。

img/458464_2_En_15_Fig2_HTML.jpg

图 15-2

正确的密码

img/458464_2_En_15_Fig1_HTML.jpg

图 15-1

密码不正确

分析

让我们更详细地看看这个程序。

程序

在这个程序中,当两个密码(输入的和存储的)一致时,执行一些活动,当它们不一致时,执行不同的活动。在这种情况下,你可以通过适当的信息允许或拒绝用户(见图 15-3 )。

img/458464_2_En_15_Fig3_HTML.jpg

图 15-3

程序流程

程序分支

一般来说,程序分支意味着根据条件的满足采取不同的路径(见图 15-4 )。

img/458464_2_En_15_Fig4_HTML.jpg

图 15-4

分支

句法

对于分支,C# 使用如下所示的if-else结构:

if (condition)
{
  Statements to perform when the condition holds
}
else
{
  Statements to perform otherwise
}

解决办法

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter password: ");
    string enteredPassword = Console.ReadLine();

    // Password check
    if (enteredPassword == "friend")
    {
        Console.WriteLine("Password is OK, please enter");
    }
    else
    {
        Console.WriteLine("Incorrect password");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

为了阐明这个条件,我使用了一个等式测试,使用两个等号输入。如果比较值相同,测试评估为true,条件被认为满足,并且执行if分支中的语句。如果比较值不同,测试评估为false,条件被认为不满足,并且执行else分支中的语句。

试验

现在你可以检查程序是如何执行的!除了执行一个普通的程序运行,你还可以单步执行代码,就像你在上一章学到的那样。

反向条件

为了让你更熟悉情况,从不同的角度看它们是很有用的。继续讨论密码问题,让我们从另一个角度来看。

工作

现在的任务是交替地解决前面的练习,也就是把条件反过来。换句话说,你将测试不平等而不是平等。

解决办法

下面是代码:

static void Main(string[] args)
{
    // Correct password
    string correctPassword = "friend";

    // Input
    Console.Write("Enter password: ");
    string enteredPassword = Console.ReadLine();

    // Password check
    if (enteredPassword != correctPassword)
    {
        Console.WriteLine("Incorrect password");
    }
    else
    {
        Console.WriteLine("Password is OK, please enter");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

在这个练习中,我使用了一个不等式测试,它是用一个感叹号后跟一个等号键入的。当比较值不一致时,测试返回真。

长度检查

虽然两个文本只能通过比较来确定它们是相同还是不同,但是两个数字也可以通过比较来确定哪一个更长(或更短)。让我们来看看。

工作

在本节中,您将学习一个程序中的数字比较,该程序评估输入的文本是否最多四个字符长(参见图 15-5 和 15-6 )。

img/458464_2_En_15_Fig6_HTML.jpg

图 15-6

长文本

img/458464_2_En_15_Fig5_HTML.jpg

图 15-5

短文本

解决办法

据推测,您应该确定输入文本的字符数,并将其与数字 4 进行比较。在第七章中,你学习了如何确定文本的字符数——使用它的Length属性(程序是“文本作为对象”)。无论如何,如果您不记得属性的名称,您可以在文本变量的末尾添加一个点,并浏览 IntelliSense 可能性以查看什么可能是合适的,如前一章所述。

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a word: ");
    string word = Console.ReadLine();

    // Determining length
    int wordLength = word.Length;

    // Checking length
    if (wordLength <= 4)
    {
        Console.WriteLine("Word is short (at most 4 characters)");
    }
    else
    {
        Console.WriteLine("Word is long (more than 4 characters)");
    }

    // Waiting for Enter
    Console.ReadLine();
}

注意

我在这个解决方案中使用了一个小于或等于运算符,看起来像这样:<=

正数

在本节中,您将获得更多关于数字比较的练习。

工作

您将编写一个程序来评估用户输入的数字是否为正数(参见图 15-7 和 15-8 )。

img/458464_2_En_15_Fig8_HTML.jpg

图 15-8

这不是积极的

img/458464_2_En_15_Fig7_HTML.jpg

图 15-7

它是积极的

解决办法

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a number: ");
    string input = Console.ReadLine();
    int number = Convert.ToInt32(input);

    // Evaluation
    if (number > 0)
    {
        Console.WriteLine("The number is positive");
    }
    else
    {
        Console.WriteLine("The number is NOT positive");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

我使用了一个大于运算符来比较输入的数字和零。

当用户输入 0 时,你认为程序会做什么?它检查条件0 > 0并发现它不满足。因此,它显示该数字不是正数。这就是相当不寻常的信息措辞(“…非正面”)的原因,如图 15-9 所示。我没有用过“……是否定的”。

img/458464_2_En_15_Fig9_HTML.jpg

图 15-9

零的结果

奇数和偶数

让我们进行另一个数字比较。

工作

你现在的任务是编写一个程序,评估用户输入的数字是奇数还是偶数(见图 15-10 和 15-11 )。

img/458464_2_En_15_Fig11_HTML.jpg

图 15-11

确定奇数

img/458464_2_En_15_Fig10_HTML.jpg

图 15-10

确定偶数

解决办法

解决方案的核心是确定输入的数除以 2 的余数。如果余数为零,则数字为偶数。如果有余数,这个数就是奇数。

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a number: ");
    string input = Console.ReadLine();
    int number = Convert.ToInt32(input);

    // Remainder calculation
    int remainderAfterDivisionByTwo = number % 2;

    // Evaluation
    if (remainderAfterDivisionByTwo == 0)
    {
        Console.WriteLine("The number is even");
    }
    else
    {
        Console.WriteLine("The number is odd");
    }

    // Waiting for Enter
    Console.ReadLine();
}

大小写无关

你已经知道两个文本可以比较,看看他们是否相等或不相等。这种比较区分大小写。换句话说,霍比特人霍比特人被认为是不同的单词。然而,您经常需要不区分大小写的比较,我现在将向您展示这一点。

工作

在这个程序中,用户将输入两个名字,你将评估它们是相同还是不同,不考虑小写和大写的区别(见图 15-12 和 15-13 )。

img/458464_2_En_15_Fig13_HTML.jpg

图 15-13

不同的名字

img/458464_2_En_15_Fig12_HTML.jpg

图 15-12

相同的名字

解决办法

该解决方案的核心是在进行比较之前将两段文本都转换成小写。为此,您可以使用ToLower方法调用。

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter a name: ");
    string name1 = Console.ReadLine();

    Console.Write("Enter another name: ");
    string name2 = Console.ReadLine();

    // Converting to small letters
    string name1inSmall = name1.ToLower();
    string name2inSmall = name2.ToLower();

    // Evaluating
    if (name1inSmall == name2inSmall)
    {
        Console.WriteLine("You have entered the same names");
    }
    else
    {
        Console.WriteLine("You have entered different names");
    }

    // Waiting for Enter
    Console.ReadLine();
}

不带牙套

如果分支只包含一条语句,C# 允许您省略ifelse分支周围的括号。一般来说,我不推荐这种做法,因为它可能会产生误导。我现在给你看这个,只是为了让你意识到它。

工作

您将再次解决之前的练习,这一次没有括号。

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter a name: ");
    string name1 = Console.ReadLine();

    Console.Write("Enter another name: ");
    string name2 = Console.ReadLine();

    // Converting to small letters
    string name1inSmall = name1.ToLower();
    string name2inSmall = name2.ToLower();

    // Evaluating
    // BRANCHES NOT DELIMITED BY BRACES (CURLY BRACKETS)
    if (name1inSmall == name2inSmall)
        Console.WriteLine("You have entered the same names");
    else
        Console.WriteLine("You have entered different names");

    // Waiting for Enter
    Console.ReadLine();
}

两个数中较大的一个

程序员的一项常见任务是找出两个数字中哪个更大(或者更小,类似地)。

工作

你现在的任务是编写一个程序,要求用户输入两个数字,然后说出两个数字中哪个更大(见图 15-14 )。

img/458464_2_En_15_Fig14_HTML.jpg

图 15-14

确定哪个数字更大

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter first number: ");
    string input1 = Console.ReadLine();
    int number1 = Convert.ToInt32(input1);

    Console.Write("Enter second number: ");
    string input2 = Console.ReadLine();
    int number2 = Convert.ToInt32(input2);

    // Evaluating
    int greater;
    if (number1 > number2)
    {
        greater = number1;
    }
    else
    {
        greater = number2;
    }

    // Output
    Console.WriteLine("Greater of entered numbers is: " + greater);

    // Waiting for Enter
    Console.ReadLine();
}

没有 else 分支

在之前的练习中,您总是有两个分支——if分支和else分支。换句话说,你总是处于非此即彼的境地。然而,需要注意的是,如果你愿意,可以省略else分支。这意味着如果一个条件满足了,你就做一些事情,如果没有满足,你就什么都不做。看一看!

工作

在上一个练习中,您将greater变量设置为第一个值或第二个值。

现在你将以不同的方式解决同样的任务。首先,您将直接将greater变量设置为第一个值,然后如果第二个值更大,您将更改最终结果。

解决办法

下面是代码:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter first number: ");
    string input1 = Console.ReadLine();
    int number1 = Convert.ToInt32(input1);

    Console.Write("Enter second number: ");
    string input2 = Console.ReadLine();
    int number2 = Convert.ToInt32(input2);

    // Evaluating
    int greater = number1;
    if (number2 > greater)
    {
        greater = number2;
    }

    // Output
    Console.WriteLine("Greater of entered numbers is: " + greater);

    // Waiting for Enter
    Console.ReadLine();
}

使用内置函数

在这本书里,我经常从不同的角度向你展示事物。我坚信这能增进你的理解。对于当前寻找两个值中较大值的问题,我将向您展示第三种解决方法。任务如此频繁,事实上,有一个方便的内置功能。

工作

您将使用内置函数Math.Max解决前面的练习。

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter first number: ");
    string input1 = Console.ReadLine();
    int number1 = Convert.ToInt32(input1);

    Console.Write("Enter second number: ");
    string input2 = Console.ReadLine();
    int number2 = Convert.ToInt32(input2);

    // Evaluating
    int greater = Math.Max(number1, number2);

    // Output
    Console.WriteLine("Greater of entered numbers is: " + greater);

    // Waiting for Enter
    Console.ReadLine();
}

摘要

在这一章中,你开始学习程序语句的条件执行,这意味着一个或多个语句的执行或不执行可以通过一些测试来决定。您看到了以下测试示例:

  • ==操作符测试两个文本或两个数字的相等性

  • !=运算符测试两个文本或两个数字的不等式

  • >(或<)运算符测试一个数是否大于(或小于)另一个数

最后一个测试可以用>=(或<=)运算符扩展为“大于或等于”(或“小于或等于”)。

为了在代码中使用条件执行,您学习了if-else构造。这由一个条件和两个分支组成。如果条件被评估为真(满足),则执行if分支中的语句。如果条件被评估为假(未满足),则执行else分支中的语句。

您了解到,如果一个分支由一条语句组成,C# 语法允许您省略分支周围的大括号,尽管我不鼓励您这样做,因为当人们后来将一个分支扩展到几条语句时,经常会忘记包括大括号。

更重要的是,您了解到如果您愿意,可以省略else分支。这意味着没有替代行动——当条件不满足时,什么也不做。

作为奖励,您学习了有用的内置函数Math.Max。(你大概能猜到有个类似的函数叫Math.Min。)

十六、实际情况

在前一章中,你学习了程序语句的条件执行。在这一章中,你将加深对这一主题的了解。我将向您展示如何在您的编程生涯中迟早会遇到的几个简单任务中使用条件和分支。

附加扩展名

有时,您想向用户询问文件名,但您不知道用户输入的文件名是否带有扩展名。

工作

您将编写一个程序,将扩展名.png附加到输入的文件名上,除非该扩展名已经是输入的一部分(见图 16-1 和 16-2 )。

img/458464_2_En_16_Fig2_HTML.jpg

图 16-2

不追加。png 扩展

img/458464_2_En_16_Fig1_HTML.jpg

图 16-1

追加。png 扩展

解决办法

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter image name: ");
    string fileName = Console.ReadLine();

    // Appending extension (ONLY IN CASE OF NEED)
    if (!fileName.ToLower().EndsWith(".png"))
    {
        fileName += ".png";
    }

    // Output
    Console.WriteLine("We are going to use name: " + fileName);

    // Waiting for Enter
    Console.ReadLine();
}

讨论

让我们稍微讨论一下这个程序。

延伸检测

当前练习中最有趣的一点是找出输入的文件名是否以特定的扩展名结尾:

  • 首先,将文件名转换成小写,这样就不必区分.png.PNG

  • 您使用方法EndsWith来确定文本是否以特定的内容结束。在这种情况下,如果文本以.png结尾,方法调用将返回true。否则返回false

  • 使用!操作符对EndsWith方法返回的结果求反。感叹号将true变为false,反之亦然。这意味着你实际上是在问“文本不是以.png结尾的吗?”而不是“是不是以.png结尾?”。

输入条件

请注意,在指定条件时,不一定要输入比较。例如,您不必总是使用“小于”。如果条件评估为布尔值,如truefalse,这就足够了。

如果条件评估为true,则认为满足,并且执行if分支中的语句。

如果条件评估为false,则认为没有满足,并且执行else分支中的语句(或者在缺少else分支的情况下不执行任何操作)。

缺少 else 分支

示例程序缺少一个else分支。如果输入的名字以.png结尾,EndsWith方法会找到它并返回true。如果得到false,则认为条件没有满足,所以不会执行附加扩展名的语句,输入的名称保持不变。

链接

注意ToLowerEndsWith方法的链接。小写转换的输出不存储在任何变量中。相反,它作为链中下一个方法的输入,换句话说,EndsWith

头和尾

让我们再做一些关于条件的练习。

工作

你要写一个扔一次硬币的程序(见图 16-3 )。

img/458464_2_En_16_Fig3_HTML.jpg

图 16-3

扔硬币

解决办法

解决方案的核心是生成一个随机数——零或一——并随后将其转换为正面或反面。

代码如下:

static void Main(string[] args)
{
    // Random number generator
    Random randomNumbers = new Random();

    // Random number 0/1 and its transformation
    int randomNumber = randomNumbers.Next(0, 1 + 1);
    if (randomNumber == 0)
    {
        Console.WriteLine("Head tossed");
    }
    else
    {
        Console.WriteLine("Tail tossed");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

我只想提醒您,Next方法要求指定一个随机数范围的上限,并且已经增加了 1。这就是为什么你在前一个程序中写了1+1。当然,你也可以直接写2,但是1+1在我看来更符合逻辑,声明1为上限,并添加(奇怪的)必需的1

截止日期检查

俗话说,“永远不要相信用户”。这意味着作为一名程序员,你必须经常检查生产软件中用户输入的数据。

你需要检查用户数据通常不是因为恶意使用,因为 99.9%的用户没有任何滥用你的软件的意图。用户只会犯错误。这就是为什么你应该检查他们的输入并提示他们改正。

因此,现在您将学习如何实现一些输入检查。

工作

您将编写一个程序,提示用户输入订单截止日期,如果用户输入的是过去的日期,则会给出警告(见图 16-4 )。

img/458464_2_En_16_Fig4_HTML.jpg

图 16-4

查看日期

解决办法

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter order deadline: ");
    string input = Console.ReadLine();
    DateTime enteredDeadline = Convert.ToDateTime(input);

    // Checking entered value
    DateTime today = DateTime.Today;
    if (enteredDeadline < today)
    {
        Console.WriteLine("Error! You have entered date in the past.");
    }
    else
    {
        Console.WriteLine("Deadline accepted.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 要将文本形式输入的日期转换成DateTime对象,可以使用Convert.ToDateTime方法调用。

  • 如果输入不存在的日期,转换将失败。您可以使用try-catch来处理这个问题。

  • 与数字转换类似,Convert.ToDateTime可以接受第二个参数,指定转换所用的语言。

发票日期检查

让我们再做一个检查用户输入数据的练习。

工作

我国的增值税(VAT)法规要求发票开具日期不能早于付款日期,同时也不能晚于付款后 15 天。

当前的任务是执行这两项检查(见图 16-5 、 16-6 和 16-7 )。

img/458464_2_En_16_Fig7_HTML.jpg

图 16-7

接受日期

img/458464_2_En_16_Fig6_HTML.jpg

图 16-6

约会太晚

img/458464_2_En_16_Fig5_HTML.jpg

图 16-5

约会太早

解决办法

以下是解决方案:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Payment date: ");
    string inputPayment = Console.ReadLine();
    DateTime paymentDate = Convert.ToDateTime(inputPayment);

    Console.Write("Invoice date: ");
    string inputInvoice = Console.ReadLine();
    DateTime invoiceDate = Convert.ToDateTime(inputInvoice);

    // Checking
    bool ok = true;
    if (invoiceDate < paymentDate)
    {
        Console.WriteLine("Invoice date cannot precede payment date.");
        ok = false;
    }
    if (invoiceDate > paymentDate.AddDays(15))
    {
        Console.WriteLine("Invoice cannot be issued later than 15 days after payment.");
        ok = false;
    }
    if (ok)
    {
        Console.WriteLine("Dates accepted.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

在这个解决方案中,您使用了一个名为ok的辅助变量。变量监控一切是否正常。一开始,你把它设置为true。如果执行的任何检查失败,您将该值切换到false。如果变量在两次检查后都保持true,您就知道一切正常,并向用户显示一条确认消息。

西班牙语星期几

现在,您将学习如何将代码的执行分成多个分支。

工作

您将编写一个程序,显示用户输入的日期的西班牙语版本的星期几(月、月、日等等)(见图 16-8 )。

img/458464_2_En_16_Fig8_HTML.jpg

图 16-8

用西班牙语显示日期

解决办法

您可以使用DateTime对象的DayOfWeek属性来查找星期几。可以使用一系列条件进行到西班牙语的转换。

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a date: ");
    string input = Console.ReadLine();
    DateTime enteredDate = Convert.ToDateTime(input);

    // Finding day of week (in enumeration)
    DayOfWeek dayOfWeek = enteredDate.DayOfWeek;

    // Spanish texts
    string spanish = "";
    if (dayOfWeek == DayOfWeek.Monday)
        spanish = "Lunes";
    if (dayOfWeek == DayOfWeek.Tuesday)
        spanish = "Martes";
    if (dayOfWeek == DayOfWeek.Wednesday)
        spanish = "Miercoles";
    if (dayOfWeek == DayOfWeek.Thursday)
        spanish = "Jueves";
    if (dayOfWeek == DayOfWeek.Friday)
        spanish = "Viernes";
    if (dayOfWeek == DayOfWeek.Saturday)
        spanish = "Sábado";
    if (dayOfWeek == DayOfWeek.Sunday)
        spanish = "Domingo";

    // Output
    Console.WriteLine(spanish);
    if (enteredDate == new DateTime(1945, 5, 8))
        Console.WriteLine("The happiest day of the 20th century.");

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

img/458464_2_En_16_Fig9_HTML.jpg

图 16-9

使用 DayOfWeek 枚举

  • 您已经省略了围绕单个if分支的大括号。您可以这样做,因为每个分支中只有一个语句。我通常不这样做,但是在这种有许多简单的if的情况下,对我来说这似乎会使代码更整洁。

  • 一周中的每一天都是DayOfWeek枚举的成员。在输入两个等号后,只要按下键盘上的空格键,Visual Studio 就会为您提供枚举(参见图 16-9 )。使用 Visual Studio 提供的功能!

交换语句

对于某些多重分支的情况,C# 中也有一个switch语句。现在你将学习如何使用它。

工作

您将使用switch语句解决最后一个任务。

解决办法

下面是代码:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a date: ");
    string input = Console.ReadLine();
    DateTime enteredDate = Convert.ToDateTime(input);

    // Finding day of week (in enumeration)
    DayOfWeek dayOfWeek = enteredDate.DayOfWeek;

    // Spanish texts
    string spanish = "";
    switch (dayOfWeek)
    {
        case DayOfWeek.Monday:
            spanish = "Lunes";
            break;
        case DayOfWeek.Tuesday:
            spanish = "Martes";
            break;
        case DayOfWeek.Wednesday:
            spanish = "Miercoles";
            break;
        case DayOfWeek.Thursday:
            spanish = "Jueves";
            break;
        case DayOfWeek.Friday:
            spanish = "Viernes";
            break;
        case DayOfWeek.Saturday:
            spanish = "Sábado";
            break;
        case DayOfWeek.Sunday:
            spanish = "Domingo";
            break;
    }

    // Output
    Console.WriteLine(spanish);
    if (enteredDate == new DateTime(1945, 5, 8))
        Console.WriteLine("The happiest day of the 20th century.");

    // Waiting for Enter
    Console.ReadLine();
}

讨论

如果重复的分支总是基于相同的值,您可以使用switch语句作为if序列的替换。这是本例中的dayOfWeek变量的值。

至于语法,switch关键字后面(在括号中)是一个变量(或表达式),它的值决定了执行将采用哪个分支。各个分支以关键字case开始,后跟控制变量的特定值和一个冒号。你应该用break关键字结束每个分支。

摘要

在这一章中,你为各种实际任务编写了有条件执行的程序。具体来说,您学到了以下内容:

  • 输入不带任何关系运算符的条件,如<==等。条件简单地评估为bool类型。当评估结果为true时,视为完成。

  • 使用!运算符否定条件。

  • 将随机数转换成另一种数据,如正面/反面对。

  • 对用户输入执行各种检查,尤其是日期。

  • 通过使用一系列if语句或使用switch语句,将程序分支到几个可选的执行路径。

十七、复合条件

你现在已经有了一些用公式表达条件,并用它们来解决实际问题的经验。对于更复杂的问题,你经常需要的是把两个或更多的部分条件组合起来。这就是你将在本章学习的内容。

是或否

复合条件的第一个用途是检查用户输入是否属于允许的选项之一。

工作

您将编写一个程序来检查用户输入的还是否。所有其他输入都将被视为不正确(参见图 17-1 和 17-2 )。

img/458464_2_En_17_Fig2_HTML.jpg

图 17-2

是啊!

img/458464_2_En_17_Fig1_HTML.jpg

图 17-1

可以接受的回答但是很难过

解决办法

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Do you love me? ");
    string input = Console.ReadLine();

    // Evaluating
    string inputInSmall = input.ToLower();
    if (inputInSmall == "yes" || inputInSmall == "no")
    {
        Console.WriteLine("OK.");
    }
    else
    {
        Console.WriteLine("Say it straight!");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 为了忽略大小写的差异,您将输入转换为小写字母。

  • 使用的条件是复合条件。它由使用条件 OR 运算符连接的两个部分条件组成,类型为||(两条垂直线)。

  • 如果部分条件的至少一个被满足,则条件被满足(并且if分支被执行)。这意味着用户输入了否。在这种情况下,选项是互斥的。但是,您会遇到两个条件同时满足的情况。

  • 如果第一或第二部分条件都不满足,则条件不满足(并且执行else分支)。换句话说,用户输入了除是或否之外的内容。

用户名和密码

现在,您将看到应该同时满足的部分条件。

工作

您将编写一个程序,检查用户是否输入了正确的用户名(Orwell) 并同时输入了正确的密码(Catalonia)。用户名不区分大小写,这意味着它可以是小写和大写(参见图 17-3 和 17-4 )。

img/458464_2_En_17_Fig4_HTML.jpg

图 17-4

正确的用户名和密码

img/458464_2_En_17_Fig3_HTML.jpg

图 17-3

用户名正确,但密码不正确

解决办法

代码如下:

static void Main(string[] args)
{
    // Correct values
    string correctUsername = "Orwell";
    string correctPassword = "Catalonia";

    // Inputs
    Console.Write("User name: ");
    string enteredUserName = Console.ReadLine();

    Console.Write("Password: ");
    string enteredPassword = Console.ReadLine();

    // Evaluating
    if (enteredUserName.ToLower() == correctUsername.ToLower() &&
        enteredPassword == correctPassword)
    {
        Console.WriteLine("Thanks for your books!");
    }
    else
    {
        Console.WriteLine("Could not log you in.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 使用的条件也是一个复合条件。它的部分条件使用条件 AND 运算符连接,该运算符的类型为&&(两个&符号)。

  • 如果两个部分条件同时满足,则条件满足(执行if分支)。这意味着用户必须输入正确的用户名和密码。

  • 不满足条件(并因此执行else分支),不满足任何一个部分条件就足够了。

裤子

您甚至可以组合几个 AND 和 OR 操作符来得到一个真正复杂的复合条件。看一看!

工作

您将修改前面的任务,以允许两个可能的用户登录。两者都有自己的密码。

解决办法

代码如下:

static void Main(string[] args)
{
    // Correct values
    string correctUsername1 = "Orwell";
    string correctPassword1 = "Catalonia";

    string correctUsername2 = "Blair";
    string correctPassword2 = "1984";

    // Inputs
    Console.Write("User name: ");
    string enteredUsername = Console.ReadLine();

    Console.Write("Password: ");
    string enteredPassword = Console.ReadLine();

    // Evalulating
    if (enteredUsername.ToLower() == correctUsername1.ToLower() &&
        enteredPassword == correctPassword1 ||
        enteredUsername.ToLower() == correctUsername2.ToLower() &&
        enteredPassword == correctPassword2)
    {
        Console.WriteLine("Thanks for your books!");
    }
    else
    {
        Console.WriteLine("Could not log you in.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 您可以将两个条件运算符:AND 与 OR 结合使用。

  • 满足完整条件要求用户输入正确的第一用户名和正确的第一密码,或者输入正确的第二用户名和正确的第二密码。

  • 与 or 运算符相比,条件有意为 AND 运算符使用更高优先级的*(优先级)。具体来说,首先评估两个潜在用户,然后对部分结果进行“或”运算。*

** 如果需要不同的求值顺序,只需像数学一样使用圆括号(圆括号)即可。*

*## 条件的预先计算

前面练习中的复合条件已经相当复杂了。要理解这一点,阅读时必须集中注意力。在类似的情况下,预先计算(提前计算)部分条件可能更好。这就是我现在要给你看的。

工作

任务和上一个是一样的,但是解决方案会不一样。

解决办法

代码如下:

static void Main(string[] args)
{
    // Correct values
    string correctUsername1 = "Orwell";
    string correctPassword1 = "Catalonia";

    string correctUsername2 = "Blair";
    string correctPassword2 = "1984";

    // Inputs
    Console.Write("User name: ");
    string enteredUsername = Console.ReadLine();
    Console.Write("Password: ");
    string enteredPassword = Console.ReadLine();

    // Evaluating
    bool user1ok = enteredUsername.ToLower() == correctUsername1.ToLower() &&
                    enteredPassword == correctPassword1;
    bool user2ok = enteredUsername.ToLower() == correctUsername2.ToLower() &&
                    enteredPassword == correctPassword2;
    if (user1ok || user2ok)
    {
        Console.WriteLine("Thanks for your books!");
    }
    else
    {
        Console.WriteLine("Could not log you in.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 您一个接一个地检查两个用户。这样,主条件就可以用一种清晰简洁的方式写出来。

  • 部分条件被预先计算成bool类型的变量。当条件满足时,相应变量的值被设置为true

是或否反转

你已经在第十五章中学习了反转条件。在那一章中,条件很简单。现在,您将逆转一个复合条件,这有点棘手,需要更加小心。

工作

你将再次回到本章开头的“是或否”项目。出于练习复合条件的目的,考虑如何颠倒原始条件来交换ifelse分支。

解决办法

下面是代码:

static void Main(string[] args)
{
    // Input
    Console.Write("Do you love me? ");
    string input = Console.ReadLine();

    // Evaluating
    string inputInSmall = input.ToLower();
    if (inputInSmall != "yes" && inputInSmall != "no")
    {
        Console.WriteLine("Say it straight!");
    }
    else
    {
        Console.WriteLine("OK.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

请注意以下几点:

  • 您现在检查的不是正确的输入,而是不正确的输入。

  • 当输入既不等于“是”也不等于“否”时,则输入不正确。

  • 颠倒条件导致 OR 运算符变为 AND 运算符。它还导致平等变成不平等。

等级检查

现在我想把你的注意力转向一个属于特定集合或特定范围的数字的频繁测试。以下两项任务与此相关。

工作

用户输入学生的成绩。然后,程序将检查输入的数字是否在可能值 1、2、3、4 或 5 的集合中(见图 17-5 和 17-6 )。

img/458464_2_En_17_Fig6_HTML.jpg

图 17-6

不在范围内

img/458464_2_En_17_Fig5_HTML.jpg

图 17-5

在范围内

解决办法

这个条件可以用列举单个选择的公式来表达。为了简单起见,我不检查可能的非数字输入。您可以像往常一样使用try-catch自行处理。

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a grade: ");
    string input = Console.ReadLine();
    int grade = Convert.ToInt32(input);

    // Evaluating
    if (grade == 1 ||
        grade == 2 ||
        grade == 3 ||
        grade == 4 ||
        grade == 5)
    {
        Console.WriteLine("Input OK.");
    }
    else
    {
        Console.WriteLine("Incorrect input.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

更好的范围检查

允许的数字(可能的等级)实际上构成了一个一到五的范围(一个连续的没有间隙的范围)。在这种情况下,您可以使用更好的方法来检查一个数字是否属于特定的范围。

工作

任务是使用范围检查解决前面的练习。

解决办法

当一个数大于或等于下界,同时又小于或等于上界时,它就属于由其下界和上界给定的范围。

代码如下:

static void Main(string[] args)
{
    // Input
    Console.Write("Enter a grade: ");
    string input = Console.ReadLine();
    int grade = Convert.ToInt32(input);

    // Evaluating
    if (grade >= 1 && grade <= 5)
    {
        Console.WriteLine("Input OK.");
    }
    else
    {
        Console.WriteLine("Incorrect input.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

摘要

本章向您介绍了复合条件的主题。您已经了解到,if语句条件可以通过使用条件 AND 和条件 OR 操作符将几个部分条件连接在一起来复合。

在 C# 中,AND 运算符被写成&&,当两个部分条件都满足时,它的计算结果为true。另一方面,OR 运算符被写成||,当至少一个部分条件满足时,它的计算结果为true

您还看到了大量的部分条件组合成一个条件。在这种情况下,运算符优先级的问题很重要。如果没有括号,则和总是在或之前计算。但是,请注意,这些条件可能会变得相当复杂和难以理解。建议预先分别计算整个条件的各个部分,并将它们临时存储在bool类型的变量中。

我还试图让你注意到逆转复合条件的问题,这需要额外的关注和专注才能做好。具体来说,您了解到在反转时,and 被切换为 or(反之亦然),等式变为不等式(反之亦然)。

最后,我向您展示了如何检查一个数字是属于指定的集合还是指定的范围。在后一种情况下,您对范围的下限和上限执行了同步测试。*

十八、多重条件

继续讨论条件这个话题,现在我们来看更复杂的例子。在这一章中,你将遇到可以在一个程序中使用几个条件来解决的任务。

足球

首先,您将详细考虑可选执行路径的三个分支的典型情况。

工作

您将准备一个程序,用户在其中输入关于足球比赛的数据:双方的进球数。然后,程序评估匹配结果。它显示第一个俱乐部赢了,第二个俱乐部赢了,还是平局(见图 18-1 、 18-2 和 18-3 )。

img/458464_2_En_18_Fig3_HTML.jpg

图 18-3

第二个俱乐部赢了

img/458464_2_En_18_Fig2_HTML.jpg

图 18-2

这是一个平局

img/458464_2_En_18_Fig1_HTML.jpg

图 18-1

第一个俱乐部赢了

分析

您可以连续使用三个条件来解决任务,每个条件考虑一个特定的匹配结果(参见图 18-4 )。

img/458464_2_En_18_Fig4_HTML.jpg

图 18-4

程序流程

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Goals scored by Liverpool: ");
    string inputLiverpool = Console.ReadLine();
    int goalsLiverpool = Convert.ToInt32(inputLiverpool);

    Console.Write("Goals scored by Manchester: ");
    string inputManchester = Console.ReadLine();
    int goalsManchester = Convert.ToInt32(inputManchester);

    // Evaluating
    if (goalsLiverpool > goalsManchester)
    {
        Console.WriteLine("Liverpool won.");
    }

    if (goalsLiverpool == goalsManchester)
    {
        Console.WriteLine("Tie.");
    }

    if (goalsLiverpool < goalsManchester)
    {
        Console.WriteLine("Manchester won.");
    }

    // Waiting for Enter
    Console.ReadLine();
}

足球或者

为了给你展示另一个观点,你将用另一种方法解决前面的练习。之前,您连续使用了三个条件。这一次,您将第二个条件嵌套到第一个条件中。

分析

如图 18-5 所示,程序将首先分支到以下选项:

img/458464_2_En_18_Fig5_HTML.jpg

图 18-5

程序流程

  • 利物浦赢了。

  • 利物浦没有赢。

另一个选项“利物浦没有赢”,将进一步分为以下内容:

  • 领带。

  • 曼彻斯特赢了。

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Goals scored by Liverpool: ");
    string inputLiverpool = Console.ReadLine();
    int goalsLiverpool = Convert.ToInt32(inputLiverpool);

    Console.Write("Goals scored by Manchester: ");
    string inputManchester = Console.ReadLine();
    int goalsManchester = Convert.ToInt32(inputManchester);

    // Evaluating
    if (goalsLiverpool > goalsManchester)
    {
        // Here we know Liverpool won. We can display the result.
        Console.WriteLine("Liverpool won.");
    }
    else
    {
        // Here we know Liverpool did not win. We will decide
        //   between tie and victorious Manchester
        if (goalsLiverpool == goalsManchester)
        {
            Console.WriteLine("Tie.");
        }
        else
        {
            Console.WriteLine("Manchester won.");
        }
    }

    // Waiting for Enter
    Console.ReadLine();
}

最少三个数字

下一个示例使用条件执行来比较三个数字。

工作

你将编写一个程序,找出用户输入的三个数字中最小的一个(见图 18-6 )。

img/458464_2_En_18_Fig6_HTML.jpg

图 18-6

寻找最小的数字

分析

该任务可以通过对所有输入数字的后续处理来解决。您将使用一个辅助变量来存储到目前为止找到的最小值。

开始时,第一个输入的数字成为最小值。在第二步中,您将第二个数字与最小值进行比较。如果前者小于后者,则前者成为最小值。最后,对第三个数字执行相同的程序。

解决办法

下面是代码:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter 1\. number: ");
    string input1 = Console.ReadLine();
    int number1 = Convert.ToInt32(input1);

    Console.Write("Enter 2\. number: ");
    string input2 = Console.ReadLine();
    int number2 = Convert.ToInt32(input2);

    Console.Write("Enter 3\. number: ");
    string input3 = Console.ReadLine();
    int number3 = Convert.ToInt32(input3);

    // At the beginning, we set 1st number as minimum
    int minimum = number1;

    // Is not 2nd number less than present minimum?
    if (number2 < minimum)
    {
        minimum = number2;
    }

    // Is not 3rd number less than present minimum?
    if (number3 < minimum)
    {
        minimum = number3;
    }

    // Output
    Console.WriteLine("The least of entered numbers is " + minimum);

    // Waiting for Enter
    Console.ReadLine();
}

内置函数的最小值

您可以使用 C# 中现成的Math.Min函数来解决前面的练习。函数本身确定两个数字中最小的一个。我将向你展示如何使用三个数字的情况。

解决办法

首先,确定第一个和第二个数字中最小的一个。然后,结果将与第三个“竞争”。

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter 1\. number: ");
    string input1 = Console.ReadLine();
    int number1 = Convert.ToInt32(input1);

    Console.Write("Enter 2\. number: ");
    string input2 = Console.ReadLine();
    int number2 = Convert.ToInt32(input2);

    Console.Write("Enter 3\. number: ");
    string input3 = Console.ReadLine();
    int number3 = Convert.ToInt32(input3);

    // Evaluating
    int min12 = Math.Min(number1, number2);
    int minimum = Math.Min(min12, number3);

    // Output
    Console.WriteLine("The least of entered numbers is " + minimum);

    // Waiting for Enter
    Console.ReadLine();
}

线性方程

这个练习会涉及到一些数学知识。

工作

您将编写一个程序来求解一个线性方程,换句话说,一个类型为 ax + b = 0 的方程。

比如 2x + 6 = 0 是一个线性方程,2 是 a ,6 是 b

解决方案显然是-3。当你用-3 代替 x 时,左边变成零,换句话说,等于右边。

用户以系数 ab 的形式输入要求解的方程。然后程序计算并显示其解(见图 18-7 )。

img/458464_2_En_18_Fig7_HTML.jpg

图 18-7

计算并显示其解

分析

无论何时你想编程任何东西,你都需要先了解现实世界的问题。换句话说,你需要知道不用电脑怎么解。

以下是如何解线性方程的数学提示:

  • 如果 a 不为零,显而易见的解是 -b/a

  • a 等于零的情况是一种数学上的好奇。方程退化为一个奇怪的“没有 x 的方程”或者伪方程 b = 0 。这样一个“等式”

    • 对于等于零的 b 有无穷多个解(不管 x 如何,它总是成立)

    • 对于非零的 b 没有解(没有 x 可以满足这个方程)

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter a: ");
    string inputA = Console.ReadLine();
    double a = Convert.ToDouble(inputA);

    Console.Write("Enter b: ");
    string inputB = Console.ReadLine();
    double b = Convert.ToDouble(inputB);

    // Solving the equation
    if (a != 0)
    {
        // a is non-zero, the equation has "normal" solution
        double solution = -b / a;
        Console.WriteLine("Solution is x=" + solution);
    }
    else
    {
        // a is zero, result depends on b
        if (b == 0)
        {
            Console.WriteLine("The equation \"is solved\" by any x");
        }
        else
        {
            Console.WriteLine("The equation does not have a solution");
        }
    }

    // Waiting for Enter
    Console.ReadLine();
}

二次方程

继续数学,下一个练习涉及一个更难的二次方程。

工作

你会写一个程序来解一个二次方程,换句话说就是一个类似ax2+bx+c = 0的方程。二次方程的一个例子是x2-x- 2 = 0其中 a 为 1, b 为-1, c 为-2。提到的方程有两个解:-1 和 2。替换左边两个零中的任何一个。

待解方程将以系数 abc 的形式输入。程序计算并显示其解(见图 18-8 )。

img/458464_2_En_18_Fig8_HTML.jpg

图 18-8

解二次方程

为了简单起见,您不会考虑 a 等于零的情况,这将把任务转移到前一个线性方程。

分析

很久以前,有人聪明地设计出了一个解二次方程的程序。你可能在学校就知道了。你先算一下所谓的判别式:

D={b}²-4 ac

然后,解决方案根据判别值进行分支。

  • 对于 D > 0 ,该方程有两个解,由下式给出:

{x}_{1,2}=\frac{-b\pm \sqrt{D}}{2a}

  • 对于 D = 0 ,同样的公式适用于两个解重合的情况。

  • 对于 D < 0 ,该方程没有实数解。

解决办法

代码如下:

static void Main(string[] args)
{
    // Inputs
    Console.Write("Enter a: ");
    string input = Console.ReadLine();
    double a = Convert.ToDouble(input);

    Console.Write("Enter b: ");
    string inputB = Console.ReadLine();
    double b = Convert.ToDouble(inputB);

    Console.Write("Enter c: ");
    string inputC = Console.ReadLine();
    double c = Convert.ToDouble(inputC);

    // Solving + output
    double d = b * b - 4 * a * c;
    if (d > 0)
    {
        double x1 = (-b - Math.Sqrt(d)) / (2 * a);
        double x2 = (-b + Math.Sqrt(d)) / (2 * a);
        Console.WriteLine("The equation has two solutions:");
        Console.WriteLine(x1);
        Console.WriteLine(x2);
    }
    if (d == 0)
    {
        double x = -b / (2 * a);
        Console.WriteLine("The equation has a single solution: " + x);
    }
    if (d < 0)
    {
        Console.WriteLine("The equation does not have a solution");
    }

    // Waiting for Enter
    Console.ReadLine();
}

讨论

这个练习最有趣的一点是你用代码输入公式的方式。请注意,分子和分母必须用括号括起来,以确定计算的正确顺序!数学公式不包含它们,因为数学家使用分数。

计算判别式时,我不使用括号;我只是依靠乘法优先于减法。

试验

为了检查程序计算是否正确,您可以编写更多的代码作为测试;将溶液替换为 x 后,左侧应为零。

摘要

在本章中,您看到了几个使用多个条件来完成指定任务的例子。

首先,你用两种方法解决了足球比赛评估。第一个使用三个简单的if语句一个接一个地考虑各个可能性。第二个使用了嵌套在另一个分支中的分支。

您进一步连续练习了多个条件,以找到三个数字中最小的一个。为此,您在一个辅助变量中存储了一个“迄今为止最小”值。

然后使用内置函数Math.Min解决了相同的任务。您已经知道函数决定了两个值中的最小值。在这里,我向您展示了一个有趣的案例,告诉您如何将它用于三个数字。

在最后两个任务中,你练习了数学中的多个条件,即解线性和二次方程。最后一项任务让您有机会看到用代码编写的更复杂的计算。