用 C++ 创建控制台计算器

C++程序员通常的起点是一个在命令行上运行的“Hello, world!” 应用程序。 从本文开始,然后转到更具挑战性的内容:计算器应用。

先决条件

  • 已在您的计算机上安装并运行带有C++桌面开发工作负载的Visual Studio。 若要安装它,请参阅 Visual Studio 中的“安装C++支持”。
  • 本教程演示了一项称为“编辑并继续”的功能,使你可以在应用运行时更改代码。 若要启用编辑并继续,请在主菜单中选择“ 工具>选项>调试>常规 ”,并确保选中 “要求源文件与原始版本完全匹配 ”。

创建应用项目

Visual Studio 使用 项目 来组织应用的代码,以及用于组织一个或多个项目 的解决方案 。 项目包含用于生成应用的所有选项、配置和规则。 它还管理所有项目文件和任何外部文件之间的关系。 若要创建应用,请先创建新的项目和解决方案。

  1. 启动 Visual Studio--“Visual Studio 开始”对话框随即出现。 选择“ 创建新项目 ”以开始。

    Visual Studio 2022 启动时出现的对话框的屏幕截图。

    该对话框具有克隆存储库、打开项目或解决方案、打开本地文件夹和创建新项目的选项。

  2. 在“ 创建新项目 ”对话框中,将语言下拉列表设置为 C++,将平台下拉列表设置为 Windows,从项目类型列表中选择 控制台应用 ,然后选择“ 下一步”。

    Visual Studio“创建新项目”对话框的屏幕截图。

    语言下拉列表设置为C++,平台下拉列表设置为 Windows,项目类型(如空项目、控制台应用、CMake 项目、Windows 桌面向导等)显示在项目类型列表中。

    重要

    请确保选择 控制台应用 模板C++版本。 它具有 C++Windows控制台 标记,图标在角处具有“++”。

  3. 在“ 配置新项目 ”对话框中,选择 “项目名称 ”文本框,将新项目命名为 CalculatorTutorial,然后选择“ 创建”。

    Visual Studio“配置新项目”对话框的屏幕截图。它具有项目名称、项目位置和解决方案名称的字段。

    将创建一个空C++ Windows 控制台应用程序“Hello World”应用。 控制台应用程序使用 Windows 控制台窗口显示输出并接受用户输入。 在 Visual Studio 中,将打开编辑器窗口并显示生成的代码:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    
    int main()
    {
        std::cout << "Hello World!\n";
    }
    
    // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
    // Debug program: F5 or Debug > Start Debugging menu
    
    // Tips for Getting Started:
    //   1. Use the Solution Explorer window to add/manage files
    //   2. Use the Team Explorer window to connect to source control
    //   3. Use the Output window to see build output and other messages
    //   4. Use the Error List window to view errors
    //   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
    //   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
    

验证新应用是否生成并运行

新 Windows 控制台应用程序的模板创建一个简单的C++“Hello World”应用。 此时,可以看到 Visual Studio 如何生成和运行从 IDE 直接创建的应用。

  1. 若要生成项目,请从“生成”菜单中选择“生成解决方案”。 输出 窗口显示构建过程的结果。

    Visual Studio 输出窗口的屏幕截图。它显示生成成功的消息。

  2. 若要运行代码,请在菜单栏上选择 调试>不带调试启动 (Ctrl+F5)。

    显示应用程序的输出的 Visual Studio 调试控制台的屏幕截图:Hello World!

    此时会打开控制台窗口,应用在其中运行。

    在 Visual Studio 中启动控制台应用时,它会运行代码,然后打印“按任意键关闭此窗口。 . “为你提供了查看输出的机会。”

    祝贺! 已在 Visual Studio 中创建第一个“Hello, world!” 控制台应用!

  3. 按键关闭控制台窗口并返回到 Visual Studio。

现在,你拥有在每次更改后生成和运行应用的工具,以验证代码是否仍按预期工作。 稍后,我们将向你展示如何调试它(如果没有)。

编辑代码

现在,让我们将此模板中的代码修改为计算器应用。

  1. 将文件的内容 CalculatorTutorial.cpp 替换为以下代码,使其与此示例匹配:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b"
            << endl;
        return 0;
    }
    
    // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
    // Debug program: F5 or Debug > Start Debugging menu
    // Tips for Getting Started:
    //   1. Use the Solution Explorer window to add/manage files
    //   2. Use the Team Explorer window to connect to source control
    //   3. Use the Output window to see build output and other messages
    //   4. Use the Error List window to view errors
    //   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
    //   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
    

    了解代码:

    • #include 语句在其他文件中引入代码。 有时,你可能会看到用尖括号括住的文件名,例如 <iostream>。 尖括号指示编译器先在标准系统目录中查找 iostream 头文件,如果未找到,则查找特定于项目的目录。 其他时候,你可能会看到文件名被引号括起来,例如 "someHeader.h"。 引号指示编译器跳过在标准系统目录中查找,而只查找特定于项目的目录。
    • using namespace std; 命令告知编译器预期C++标准库中的代码将用于此文件。 如果没有此行,库中的每个关键字必须前面有 std:: 表示其范围。 例如,如果没有该行,每个对cout的引用都会写为std::cout。 添加了该 using 语句,以便更方便地访问另一个命名空间中的代码。
    • 关键字 cout 用于在 C++ 中输出到标准输出。 运算符 << 告知编译器将其右侧的任何内容发送到标准输出。
    • 关键字 endl 类似于 Enter 键;它将行结束并将光标移动到下一行。 最好将\n放在""所包含的字符串中以执行相同的操作,因为endl始终会刷新缓冲区,这可能会损害程序的性能。 但是,由于这是一个非常小的应用,因此改用endl
    • 所有C++语句都必须以分号结尾,并且所有C++应用程序必须包含一个 main() 函数。 此函数是程序在启动时运行的内容。 必须可从 main() 中访问所有代码才能使用。
  2. 若要保存文件,请按 Ctrl+S,或在菜单栏下的工具栏中选择软盘图标。

  3. 若要运行应用程序,请按 Ctrl+F5 或转到 “调试 ”菜单,然后选择“ 在没有调试的情况下启动”。 应会看到如下所示的控制台窗口。

  4. 完成后关闭控制台窗口。

添加代码以执行一些数学运算

类就像是用来定义对象功能的蓝图。 在这种情况下,我们将定义一个计算器类来包含数学逻辑。

添加 Calculator 类

  1. 转到 “项目” 菜单,然后选择“ 添加类”。 在 “类名 ”编辑框中,输入 计算器。 选择“确定”

    Visual Studio“添加类”对话框的屏幕截图。

    类名字段包含文本计算器。 .h 文件字段包含 Calculator.h。 .cpp文件字段包含Calculator.cpp。 基类字段为空。 内联选项和托管选项处于未选中状态。

    将两个新文件添加到项目中。 若要同时保存所有已更改的文件,请按 Ctrl+Shift+S。 它是 文件>全部保存的键盘快捷方式。 还有一个工具栏按钮用于 “全部保存”,这是两个软盘的图标,位于 “保存 ”按钮旁边。 通常,最好经常执行 “全部保存 ”,因此不会错过保存任何更改。

    “添加类”向导创建.h.cpp具有与类同名的文件。 可以在 “解决方案资源管理器” 窗口中看到项目文件的完整列表,该列表显示在 IDE 的一侧。 如果窗口不可见,请通过 “视图>解决方案资源管理器”从菜单栏中打开它。

    Visual Studio 解决方案资源管理器窗口的屏幕截图。

    计算器教程项目具有包含 Calculator.h 的头文件节点。 源文件节点包含Calculator.cpp和CalculatorTutorial.cpp。 引用、外部依赖项和资源文件的节点可见,但已关闭。

    可以通过在 “解决方案资源管理器” 窗口中双击该文件来打开文件。 双击 Calculator.h 将其打开。

  2. Calculator.h 以下内容的内容替换为以下代码,以便文件现在如下所示:

    #pragma once
    class Calculator
    {
    public:
        double Calculate(double x, char oper, double y);
    };
    

    了解代码

    • 此代码声明一个名为的新函数,该函数 Calculate处理加法、减法、乘法和除法的数学运算。
    • C++代码组织到 标头.h) 文件和 源文件.cpp) 文件中。 其他一些文件扩展名由各种编译器支持,但这些是需要了解的主要文件扩展名。 函数和变量通常 声明,即在头文件中指定名称和类型,并在源文件中 实现或给定定义。 若要访问另一个文件中定义的代码,可以使用 #include "filename.h"该文件的名称,该文件 filename.h 的名称声明要使用的变量或函数。
    • 最好根据代码的作用将代码组织到不同的文件中,以便以后可以轻松找到所需的代码。 在我们的案例中,我们将Calculator类与包含main()函数的文件单独定义,但计划在main()中引用Calculator类。
  3. 绿色波浪线会出现在Calculate下方,因为虽然函数Calculate声明,但未定义。 将鼠标悬停在Calculate,点击螺丝刀图标上的向下箭头,然后选择Calculator.cpp中创建“计算”的定义

    Visual Studio 编辑器窗口中工具栏下拉菜单的屏幕截图。突出显示了“在 Calculator.cpp 中创建 Calculate 定义”选项。

    此代码将添加到 Calculator.cpp

    Visual Studio 编辑器的屏幕截图,其中显示了“计算”函数的定义。

    函数的定义是:double Calculator::Calculate(double x, char oper, double y) { return 0.0; }

    目前,它只返回 0.0。 让我们改变这点。

  4. 切换到 Calculator.cpp 编辑器窗口中的文件。 将 Calculator::Calculate(double x, char oper, double y) 的内容替换为:

    double Calculator::Calculate(double x, char oper, double y)
    {
        switch(oper)
        {
            case '+':
                return x + y;
            case '-':
                return x - y;
            case '*':
                return x * y;
            case '/':
                return x / y;
            default:
                return 0.0;
        }
    }
    

    了解代码

    • 该函数 Calculate 采用数字、运算符和第二个数字。 然后它会对两个数字执行请求的操作。
    • switch 语句检查提供的运算符,并执行与该作对应的事例。 default:情况是为用户键入的运算符未被任何上述case语句处理时的后备方案。 最好以更优雅的方式处理无效的用户输入,但这超出了本教程的范围。
    • 关键字 double 表示支持小数的数字类型。 这种类型的数字称为浮点数,表示 double 具有额外精度的浮点数。 这样,计算器就可以处理十进制数学和整数数学。 由于 Calculate 代码开头(这表示函数的返回类型),因此必须始终返回双精度浮点数 double ,这就是我们在默认情况下返回 0.0 的原因。
    • 该文件 .h 声明函数原型,该 原型告知编译器需要哪些参数,以及从中预期返回的类型。 .cpp该文件包含函数的所有实现详细信息。

如果此时再次编译并运行代码,它会在询问要执行哪种操作后立即退出。 因此,修改 main 函数以执行多个计算。

Calculator调用类成员函数

  1. CalculatorTutorial.cpp 中按如下更新 main 函数:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    #include "Calculator.h"
    
    using namespace std;
    
    int main()
    {
        double x = 0.0;
        double y = 0.0;
        double result = 0.0;
        char oper = '+';
    
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b"
             << endl;
    
        Calculator c;
        while (true)
        {
            cin >> x >> oper >> y;
            result = c.Calculate(x, oper, y);
            cout << "Result " << "of " << x << oper << y << " is: " << result << endl;
        }
    
        return 0;
    }
    

    了解代码

    • 由于C++程序始终从函数开始 main() ,因此我们需要从该函数调用其他代码,因此需要一个 #include 语句才能使该代码对函数 main() 可见。
    • 变量 xy变量 operresult 声明分别存储第一个数字、第二个数字、运算符和最终结果。 最好给他们一些初始值以避免未定义的行为,这就是此处执行的作。
    • Calculator c; 行声明一 c 个名为类实例 Calculator 的对象。 类本身只是计算器工作原理的蓝图;该对象是执行数学运算的特定计算器。
    • while (true) 语句是一个循环。 只要循环中的条件 () 为 true,循环中的代码将反复执行。 由于条件只是列为 true条件,因此始终为 true,因此循环将永远运行。 若要关闭程序,用户必须手动关闭控制台窗口。 否则,程序将始终等待新输入。
    • 关键字 cin 接受来自用户的输入。 输入流足够智能,可以处理控制台窗口中输入的文本行,并按顺序将其放置在列出的每个变量中。
    • 表达式 c.Calculate(x, oper, y); 调用 Calculate 前面定义的函数,并提供输入的输入值和请求的作。 然后,该函数返回一个存储在 result中的数字。
    • 最后, result 打印到控制台,用户会看到计算结果。

再次生成并测试代码

现在再次测试程序,以确保一切正常工作。

  1. Ctrl+F5 重新生成并启动应用。

  2. Enter 5+5,然后按 Enter。 验证结果是否为 10。

    显示运行程序结果的命令窗口的屏幕截图。

    应用输出消息:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5+5。 应用输出:5+5 的结果为:10

  3. 通过关闭控制台窗口来停止程序。

调试应用

由于用户可以自由地在控制台窗口中键入任何内容,因此请确保计算器处理意外输入。 我们来调试程序,而不是运行程序,以便我们可以检查它正在执行分步作的内容。

在调试器中运行应用

  1. 在行CalcuatorTutorial.cpp中设置断点: result = c.Calculate(x, oper, y); 若要设置断点,请单击编辑器窗口左边缘的灰色垂直栏中的线条旁边,以便出现红点。

    Visual Studio 编辑器的屏幕截图。表示断点的红点显示在行上:result = c.Calculate(x, oper, y)。

    现在,当我们调试程序时,执行将暂停在该行。 我们已经大致了解了该计划适用于简单情况。 由于我们不想在每次调用 Calculate()时暂停执行,因此让我们设置断点条件。

  2. 右键单击表示断点的红点,然后选择“ 条件”。 在条件的编辑框中,输入 (y == 0) && (oper == '/')。 选择 “关闭 ”按钮以保存断点条件。

    设置断点的屏幕截图

    断点位于行上:result = c dot Calculate (x, oper, y)。 “条件...”选中“条件”选项。 “条件”下拉列表设置为“条件表达式”。 条件下拉列表设置为“为真”。 条件设置为 y == 0 && oper == '/'。

    现在,当应用尝试除以 0 时,执行会在断点处暂停。

  3. 若要调试程序,请按 F5,或选择具有绿色箭头图标的 本地 Windows 调试器调试器 工具栏按钮。 在控制台应用中,如果输入类似于“5 - 0”的内容,程序的行为正常并持续运行。 但是,如果键入“10/0”,它会在断点处暂停。 可以在运算符和数字之间放置任意数量的空格: cin 足够智能,可以适当地分析输入。

    Visual Studio 编辑器的屏幕截图。程序执行在行上的条件断点处停止:result = c.Calculate(x, oper, y);。

调试器中的有用窗口

调试代码时,你可能会注意到会出现一些新窗口。 这些窗口可以帮助你的调试体验。 查看 “自动” 窗口。 “ 自动” 窗口显示变量的当前值,这些变量在当前行之前和前面至少使用了三行。 如果未看到 “自动” 窗口,请从主菜单中选择 “调试>Windows>自动”。

Visual Studio 调试器自动窗口的屏幕截图。

oper 的值为 47 “/”,结果为 5,x 为 10,y 为 0。

若要查看该函数中的所有变量,请切换到 “局部变量 ”窗口。 由于这是一个小函数,因此“自动”和“局部变量”窗口显示相同的变量。 但是,你可以在调试时修改“局部变量”窗口中这些变量的值,以查看它们对程序的影响。 在这种情况下,我们不干涉它们。 通过选择“自动”窗口底部的“局部变量”或从主菜单中选择“调试>Windows>局部变量”,打开“局部变量”窗口。

Visual Studio 中“局部变量”窗口的屏幕截图,其中显示了调试时局部变量的当前值。

oper 的值为 47 “/”,结果为 0,x 为 10,y 为 0。

还可以将鼠标悬停在代码中的变量上,以查看当前暂停执行时的当前值。 首先单击编辑器窗口,确保编辑器窗口处于焦点。

工具提示的屏幕截图,其中显示了变量“oper”的值,即 47 或“/”。

继续调试

  1. 左侧的黄色箭头显示当前执行点。 当前行调用 Calculate,因此按 F11 单步进入函数。 现在,你正在函数正文 Calculate 中执行代码。 请谨慎使用步入功能,因为它会步入您所在行上的任何函数,包括标准库函数。 可以探索标准库,但你可能更有兴趣专注于你自己的代码而不是库代码。

  2. 现在,执行点位于函数的 Calculate 开头,请按 F10 移动到程序执行中的下一行。 F10 也称为 步过。 可以使用单步跳过逐行执行,而无需深入了解行中每个部分发生的情况的详细信息。 一般情况下,应使用 “单步跳过” 而不是 “单步执行” ,除非你想深入查看从其他地方调用的代码(正如你为到达 Calculate 的主体所做的)。

  3. 继续使用 F10单步跳过 每行,直到返回到另一个文件中的 main() 函数,并在 cout 行停下。

    程序正在执行预期功能:它取第一个数字,并将其除以第二个数字。 在cout行上,将鼠标悬停在result变量上,或在“自动”窗口中查看result。 其值为 inf,它看起来不对。

    调试计算器的屏幕截图。

    调试器中的当前语句是 cout <<“Result is: ” << result << endl;在“自动”窗口中,结果为 inf。

    我们来修复它。 该 cout 行输出存储 result的任何值,因此使用 F10 再向前一行时,控制台窗口会显示:

    Visual Studio 调试控制台的屏幕截图,显示了零除操作的结果。

    应用输出:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5-0。 应用输出:结果为:5。 用户输入了 10/0。 应用输出:结果为:inf

    此结果是由于除以零未定义,因此程序无法为请求的运算提供数值答案。

修复“除以零”错误

让我们更优雅地处理零除问题,以便用户更容易理解问题。

  1. CalculatorTutorial.cpp中进行以下更改。 由于调试器功能称为 “编辑并继续”,你可以让程序在编辑时保持运行状态。 在cin >> x >> oper >> y;后添加一个if语句,检查是否除以零,如果发生这种情况,则向用户输出消息。 否则,结果将被打印。

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    #include "Calculator.h"
    
    using namespace std;
    
    int main()
    {
        double x = 0.0;
        double y = 0.0;
        double result = 0.0;
        char oper = '+';
    
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b" << endl;
    
        Calculator c;
        while (true)
        {
            cin >> x >> oper >> y;
            if (oper == '/' && y == 0)
            {
                cout << "Math error: Attempted to divide by zero!" << endl;
                continue;
            }
            else
            {
                result = c.Calculate(x, oper, y);
            }
            cout << "Result " << "of " << x << oper << y << " is: " << result << endl;
        }
    
        return 0;
    }
    
  2. F5 一次。 程序执行将继续,直到必须暂停才能请求用户输入。 再次输入 10 / 0 。 现在,打印了一条更有用的消息。 程序请求用户提供更多输入,程序继续正常运行。

    控制台窗口的屏幕截图,其中显示了实现更改以零处理除法后的最终输出。

    控制台窗口显示两行:10/0 结果为:无穷大(inf),接着是 10/0 数学错误:尝试进行零除操作。

    注释

    在调试模式下编辑代码时,有代码变得陈旧的风险。 当调试器仍在运行旧代码,但尚未使用更改对其进行更新时,将发生这种情况。 调试器会显示一个对话框,告知你何时发生这种情况。 有时,可能需要按 F5 刷新正在执行的代码。 具体而言,如果在执行点位于函数内部时对函数内部进行了更改,则需要先退出该函数,然后再进入该函数,以更新执行的代码。 如果这不起作用,并且看到错误消息,可以通过单击 IDE 顶部菜单下的工具栏中的红色方块来停止调试,然后通过输入 F5 或选择工具栏上停止按钮旁边的绿色“播放”箭头来重新开始调试。

    编辑并继续可能失败的另一个原因是,如果看到一条消息,指出“在调试选项-常规下,需要启用‘源文件必须与原始版本完全匹配’...”若要解决此问题,请在主菜单中选择工具>选项>调试>常规,并确保选中‘源文件必须与原始版本完全匹配’”。

    了解“运行”和“调试”快捷方式

    • F5调试>启动调试,将启动一个调试会话(如果尚未处于活动状态),并运行程序,直到命中断点或程序需要用户输入。 如果不需要用户输入,并且没有可用的断点可供命中,程序将终止,当程序完成运行时,控制台窗口将自行关闭。 如果程序输出到控制台,请使用 Ctrl+F5 或设置断点,然后按 F5 使窗口保持打开状态。
    • Ctrl+F5调试>无调试启动,运行应用程序而不进入调试模式。 这比调试要快一些,程序完成执行后控制台窗口将保持打开状态。
    • F10,也称为“步过”,允许你逐行执行代码,并直观地观察代码的运行方式以及每个执行步骤中的变量值。
    • F11(称为 “步入”)的工作方式类似于 “单步执行”,只是它进入执行行中调用的任何函数。 例如,如果正在执行的行调用函数,请按 F11 将指针移到函数的正文中,以便可以按照函数的代码运行,然后再返回到开始的行。 按 F10 跳过函数调用,直接移到下一行; 函数调用仍然会执行,但程序不会暂停来展示执行过程。

关闭应用

  • 如果仍在运行,请关闭控制台窗口以停止计算器应用。

添加 Git 源代码管理

创建应用后,可能需要将其添加到 Git 存储库。 我们已经为您考虑了。 借助 Visual Studio,可以使用可直接从 IDE 使用的 Git 工具轻松完成此过程。

小窍门

Git 是最常用的新式版本控制系统,因此无论你是专业开发人员还是学习如何编写代码,Git 都可以非常有用。 如果你不熟悉 Git,https://git-scm.com/ 网站是一个很好的起点。 在那里,可以找到备忘单、热门在线书籍和 Git 基本信息视频。

若要将代码与 Git 相关联,首先创建代码所在的新 Git 存储库。 操作方法如下:

  1. 在 Visual Studio 右下角的状态栏中,选择“ 添加到源代码管理”,然后选择 “Git”。

    解决方案资源管理器窗格下方的 Git 源代码管理按钮的屏幕截图,其中突出显示了“添加到源代码管理”按钮。

  2. 在“ 创建 Git 存储库 ”对话框中,登录到 GitHub。

    在其中创建新 GitHub 存储库的“创建 Git 存储库”对话框窗口的屏幕截图。

    存储库名称根据文件夹位置自动填充。 默认情况下,新存储库是专用的,这意味着你是唯一可以访问它的人。

    小窍门

    无论存储库是公共的还是专用的,最好有一个安全存储在 GitHub 上的代码的远程备份。 即使你未与团队合作,远程存储库也会让你从任何计算机获得代码。

  3. 选择“创建并推送”

    创建存储库后,状态详细信息将显示在状态栏中。

    Visual Studio 解决方案资源管理器窗格下方的存储库状态栏的屏幕截图,其中显示了分支名称和未完成的更改数。

    带有箭头的第一个图标显示当前分支中的传出/传入提交数。 可以使用此图标来拉取任何传入提交或推送任何传出提交。 还可以选择先查看这些提交。 为此,请选择图标,然后选择“ 查看传出/传入”。

    第二个带有铅笔的图标显示代码未提交的更改数。 可以选择此图标,在 Git 更改 窗口中查看这些更改。

若要详细了解如何将 Git 与应用配合使用,请参阅 Visual Studio 版本控制文档

完成的应用

祝贺! 你完成了计算器应用的代码,生成并调试了它,并将其添加到存储库,全部在 Visual Studio 中。

后续步骤

详细了解 Visual Studio for C++

C++程序员通常的起点是一个在命令行上运行的“Hello, world!” 应用程序。 从本文开始,然后转到更具挑战性的内容:计算器应用。

先决条件

创建应用项目

Visual Studio 使用 项目 来组织应用的代码,以及用于组织一个或多个项目 的解决方案 。 项目包含用于生成应用的所有选项、配置和规则。 它还管理所有项目文件和任何外部文件之间的关系。 若要创建应用,请先创建新的项目和解决方案。

  1. 在 Visual Studio 的菜单栏上,选择“ 文件>新建>项目”。 此时会打开 “新建项目” 窗口。

  2. 在左侧栏中,确保选中 “视觉对象C++ ”。 在中心内,选择 “控制台应用”。

  3. 在底部的“ 名称 ”文本框中,将新项目命名为 CalculatorTutorial,然后选择“ 确定”。

    “新建项目”对话框的屏幕截图。

    左侧选择“其他语言” > Visual C++。 在中央位置,选择了控制台应用项目类型。 “名称”文本框中输入了 "CalculatorTutorial"。

    将创建一个空C++ Windows 控制台应用程序“Hello World”应用。 控制台应用程序使用 Windows 控制台窗口显示输出并接受用户输入。 在 Visual Studio 中,将打开编辑器窗口并显示生成的代码:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    
    int main()
    {
        std::cout << "Hello World!\n";
    }
    
    // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
    // Debug program: F5 or Debug > Start Debugging menu
    
    // Tips for Getting Started:
    //   1. Use the Solution Explorer window to add/manage files
    //   2. Use the Team Explorer window to connect to source control
    //   3. Use the Output window to see build output and other messages
    //   4. Use the Error List window to view errors
    //   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
    //   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
    

验证新应用是否生成并运行

新 Windows 控制台应用程序的模板创建一个简单的C++“Hello World”应用。 此时,可以看到 Visual Studio 如何生成和运行从 IDE 直接创建的应用。

  1. 若要生成项目,请从“生成”菜单中选择“生成解决方案”。 输出 窗口显示构建过程的结果。

    Visual Studio 输出窗口的屏幕截图,其中显示了生成成功。

  2. 若要运行代码,请在菜单栏上选择 “调试”, 开始而不调试 (Ctrl+F5)。

    Visual Studio 调试控制台的屏幕截图,其中显示了输出:Hello World!

    此时会打开控制台窗口,应用在其中运行。

    在 Visual Studio 中启动控制台应用时,它会运行代码,然后打印 Press any key to close this window . . . ,让你有机会查看输出。

    祝贺! 已在 Visual Studio 中创建第一个“Hello, world!” 控制台应用!

  3. 按键关闭控制台窗口并返回到 Visual Studio。

现在,你拥有在每次更改后生成和运行应用的工具,以验证代码是否仍按预期工作。 稍后,我们将向你展示如何调试它(如果没有)。

编辑代码

现在,让我们将此模板中的代码转换为计算器应用。

  1. 将文件的内容 CalculatorTutorial.cpp 替换为以下代码,使其与此示例匹配:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b" << endl;
        return 0;
    }
    
    // Run program: Ctrl + F5 or Debug > Start Without Debugging menu
    // Debug program: F5 or Debug > Start Debugging menu
    // Tips for Getting Started:
    //   1. Use the Solution Explorer window to add/manage files
    //   2. Use the Team Explorer window to connect to source control
    //   3. Use the Output window to see build output and other messages
    //   4. Use the Error List window to view errors
    //   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
    //   6. In the future, to open this project again, go to File > Open > Project and select the .sln file
    

    了解代码:

    • #include 语句在其他文件中引入代码。 有时,你可能会看到用尖括号括住的文件名,例如 <iostream>。 尖括号指示编译器先在标准系统目录中查找 iostream 头文件,如果未找到,则查找特定于项目的目录。 其他时候,你可能会看到文件名被引号括起来,例如 "someHeader.h"。 引号指示编译器跳过在标准系统目录中查找,而只查找特定于项目的目录。
    • using namespace std; 命令告知编译器预期C++标准库中的代码将用于此文件。 如果没有此行,库中的每个关键字必须前面有 std:: 表示其范围。 例如,如果没有该行,每个对cout的引用都会写为std::cout。 添加了该 using 语句,以便更方便地访问另一个命名空间中的代码。
    • 在 C++ 中,关键字 cout 会输出到标准输出。 运算符 << 告知编译器将其右侧的任何内容发送到标准输出。
    • 关键字 endl 类似于 Enter 键;它将行结束并将光标移动到下一行。 最好在字符串内(由""包含)放置\n以执行相同的操作,因为endl总是刷新缓冲区,会影响程序的性能。 但是,由于这是一个非常小的应用,因此改用endl
    • 所有C++语句都必须以分号结尾,并且所有C++应用程序必须包含一个 main() 函数。 此函数是程序在启动时运行的内容。 必须可从 main() 中访问所有代码才能使用。
  2. 若要保存文件,请按 Ctrl+S,或在菜单栏下的工具栏中选择软盘图标。

  3. 若要运行应用程序,请按 Ctrl+F5 或转到 “调试 ”菜单,然后选择“ 在没有调试的情况下启动”。 如果收到显示 “此项目已过期”的弹出窗口,则可以再次选择“ 不显示此对话框”,然后选择“ ”以生成应用程序。 应会看到如下所示的控制台窗口:

    控制台窗口中运行的计算器应用的屏幕截图。

    控制台应用显示输出,即:计算器控制台应用程序。 请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 进程以代码 0 退出,并显示一条消息:要在调试停止时自动关闭控制台,请启用“工具 > 选项 > 调试 > 调试停止时自动关闭控制台”。 最后,屏幕上会显示一条消息,提示您按任意键关闭此窗口。

  4. 完成后关闭控制台窗口。

添加代码以执行一些数学运算

类就像是用来定义对象功能的蓝图。 在这种情况下,我们将定义一个计算器类来包含数学逻辑。

添加 Calculator 类

  1. 转到 “项目” 菜单,然后选择“ 添加类”。 在 “类名 ”编辑框中,输入 计算器。 选择“确定”

    Visual Studio“添加类”对话框的屏幕截图。

    类名字段包含文本计算器。 .h 文件字段包含 Calculator.h。 .cpp文件字段包含Calculator.cpp。 基类字段为空。 内联选项和托管选项处于未选中状态。

    类就像是用来定义对象功能的蓝图。 在本例中,我们定义计算器及其工作原理。

    将两个新文件添加到项目中。 若要同时保存所有已更改的文件,请按 Ctrl+Shift+S。 它是 文件>全部保存的键盘快捷方式。 还有一个工具栏按钮用于 “全部保存”,这是两个软盘的图标,位于 “保存 ”按钮旁边。 通常,最好经常执行 “全部保存 ”,因此在保存时不会错过任何文件。

    “添加类”向导创建.h.cpp具有与类同名的文件。 可以在 “解决方案资源管理器” 窗口中看到项目文件的完整列表,该列表显示在 IDE 的一侧。 如果 解决方案资源管理器 不可见,请从菜单栏中打开它:选择 “查看>解决方案资源管理器”。

    Visual Studio 解决方案资源管理器窗口的屏幕截图。

    计算器教程项目有一个头文件节点,其中包含 Calculator.h、stdafx.h 和 targetver.h。 源文件节点包含Calculator.cpp、CalculatorTutorial.cpp和stdafx.cpp。 引用、外部依赖项和资源文件的节点可见,但已关闭。

    可以通过在 “解决方案资源管理器” 窗口中双击该文件来打开文件。 双击 Calculator.h 将其打开。

  2. Calculator.h 以下内容的内容替换为以下代码,以便文件现在如下所示:

    #pragma once
    class Calculator
    {
    public:
        double Calculate(double x, char oper, double y);
    };
    

    了解代码

    • 此代码声明一个名为的新函数,该函数 Calculate处理加法、减法、乘法和除法的数学运算。
    • C++代码组织到 标头.h) 文件和 源文件.cpp) 文件中。 其他一些文件扩展名由各种编译器支持,但这些是需要了解的主要文件扩展名。 函数和变量通常 声明,即在头文件中指定名称和类型,并在源文件中 实现或给定定义。 若要访问另一个文件中定义的代码,可以使用 #include "filename.h"该文件的名称,该文件 filename.h 的名称声明要使用的变量或函数。
    • 最好根据代码的作用将代码组织到不同的文件中,以便以后可以轻松找到所需的代码。 在我们的案例中,我们将Calculator类与包含main()函数的文件单独定义,但计划在main()中引用Calculator类。
  3. 绿色波浪线会出现在Calculate下方,因为虽然函数Calculate声明,但未定义。 将鼠标悬停在Calculate灯泡上,单击灯泡上的向下箭头,然后在其中Calculator.cpp选择“计算”的创建定义。 此时会显示一个弹出窗口,可让你查看另一个文件中所做的代码更改。 代码已添加到 Calculator.cpp.

    显示使用灯泡下拉列表选择“在 Calculator.cpp 中创建计算定义”的视频。

    目前,它只返回 0.0。 让我们改变这点。 按 Esc 关闭弹出窗口,然后选择 “是 ”保存更改。

  4. 切换到 Calculator.cpp 编辑器窗口中的文件。 将文件的内容替换为以下代码:

    #include "Calculator.h"
    
    double Calculator::Calculate(double x, char oper, double y)
    {
        switch(oper)
        {
            case '+':
                return x + y;
            case '-':
                return x - y;
            case '*':
                return x * y;
            case '/':
                return x / y;
            default:
                return 0.0;
        }
    }
    

    了解代码

    • 该函数 Calculate 采用数字、运算符和第二个数字。 然后它会对两个数字执行请求的操作。
    • switch 语句检查提供的运算符,并执行与该作对应的事例。 default:情况是为用户键入的运算符未被任何上述case语句处理时的后备方案。 最好以更优雅的方式处理无效的用户输入,但这超出了本教程的范围。
    • 关键字 double 表示支持小数的数字类型。 这种类型的数字称为浮点数,表示 double 具有额外精度的浮点数。 这样,计算器就可以处理十进制数学和整数数学。 由于 Calculate 代码开头(这表示函数的返回类型),因此必须始终返回双精度浮点数 double ,这就是我们在默认情况下返回 0.0 的原因。
    • 该文件 .h 声明函数原型,该 原型告知编译器需要哪些参数,以及从中预期返回的类型。 .cpp该文件包含函数的所有实现详细信息。

如果此时再次编译并运行代码,它依然会在询问您要执行哪个操作后退出。 接下来,修改 main 函数以执行某些计算。

调用 Calculator 类成员函数

  1. CalculatorTutorial.cpp 中按如下更新 main 函数:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    #include "Calculator.h"
    
    using namespace std;
    
    int main()
    {
        double x = 0.0;
        double y = 0.0;
        double result = 0.0;
        char oper = '+';
    
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b" << endl;
    
        Calculator c;
        while (true)
        {
            cin >> x >> oper >> y;
            result = c.Calculate(x, oper, y);
            cout << "Result is: " << result << endl;
        }
    
        return 0;
    }
    

    了解代码

    • 由于C++程序始终从函数开始 main() ,因此我们需要从该函数调用其他代码,因此需要一个 #include 语句才能使该代码对函数 main() 可见。
    • 变量 xy变量 operresult 声明分别存储第一个数字、第二个数字、运算符和最终结果。 最好给他们指定一些初始值以避免未定义的行为,这就是在此处所采取的步骤。
    • Calculator c; 行声明一个名为 c 的对象,该对象是 Calculator 类的实例。 类本身只是计算器工作原理的蓝图;该对象是执行数学运算的特定计算器。
    • while (true) 语句是一个循环。 只要循环中的条件 () 为 true,循环中的代码就反复执行。 由于条件只是列为 true条件,因此始终为 true,因此循环将永远运行。 若要关闭程序,用户必须手动关闭控制台窗口。 否则,程序将始终等待新输入。
    • 关键字 cin 接受来自用户的输入。 输入流足够智能,可以处理控制台窗口中输入的文本行,并按顺序将其放置在列出的每个变量中。
    • 表达式 c.Calculate(x, oper, y); 调用前面定义的 Calculate 函数,并提供输入值和请求的操作。 然后,该函数返回一个存储在 result中的数字。
    • 最后, result 打印到控制台,用户会看到计算结果。

再次生成并测试代码

再次测试程序,以确保一切正常工作。

  1. Ctrl+F5 重新生成并启动应用。

  2. Enter 5+5,然后按 Enter。 验证结果是否为 10。

    运行计算器应用的命令窗口的屏幕截图。它显示 5 + 5 的结果为 10。

  3. 通过关闭控制台窗口来停止程序。

调试应用

由于用户可以自由地在控制台窗口中键入任何内容,因此请确保计算器处理意外输入。 我们这次来调试而不是运行程序,这样我们可以逐步检查它的执行过程。

在调试器中运行应用

  1. CalcuatorTutorial.cpp 中的 result = c.Calculate(x, oper, y); 行上设置断点。 若要设置断点,请单击编辑器窗口左边缘的灰色垂直栏中的线条旁边,以便出现红点。

    用户在第 23 行上设置断点的屏幕截图:result = c.Calculate(x, oper, y);。

    现在,每次调试程序时,它都会始终在该行暂停执行。 我们已经大致了解了该计划适用于简单情况。 由于我们不想每次都暂停执行,因此我们将设置有条件断点。

  2. 右键单击表示断点的红点,然后选择“ 条件”。 在条件的编辑框中,输入 (y == 0) && (oper == '/')。 完成后选择 “关闭 ”按钮以保存断点条件。

    显示条件断点窗口的屏幕截图。

    断点位于行上:result = c dot Calculate (x, oper, y)。 “条件...”选中“条件”选项。 “条件”下拉列表设置为“条件表达式”。 条件下拉列表设置为“为真”。 条件设置为 y == 0 && oper == '/'。

    如果尝试除以 0,则执行将在断点处暂停。

  3. 若要调试程序,请按 F5,或选择具有绿色箭头图标的 本地 Windows 调试器 工具栏按钮。 在控制台应用中,如果输入类似于“5 - 0”的内容,程序的行为正常并持续运行。 但是,如果键入“10/0”,它会在断点处暂停。 甚至可以在运算符和数字之间放置任意数量的空格; cin 足够聪明,可以适当地分析输入。

    显示程序在条件断点处暂停执行的视频。

    用户输入“5 - 0”。 应用输出:结果为 5。 然后,用户输入 10/0,由于满足了条件断点的条件,程序执行停止在这一行:result = c.Calculate(x,oper,y):

调试器中的有用窗口

调试代码时,你可能会注意到会出现一些新窗口。 这些窗口可以帮助你的调试体验。 查看 “自动” 窗口。 “ 自动” 窗口显示变量的当前值,这些变量在当前行之前和前面至少使用了三行。 如果未看到 “自动” 窗口,请从主菜单中选择 “调试>Windows>自动”。

Visual Studio 调试器自动窗口的屏幕截图。

oper 的值为 47 “/”,结果为 5,x 为 10,y 为 0。

若要查看该函数中的所有变量,请切换到 “局部变量 ”窗口。 由于这是一个小函数,因此“自动”和“局部变量”窗口显示相同的变量。 但是,你可以在调试时修改这些变量的值,以查看它们对程序的影响。 在这种情况下,我们不干涉它们。 通过选择“自动”窗口底部的“局部变量”或从主菜单中选择“调试>Windows>局部变量”,打开“局部变量”窗口。

Visual Studio 中“局部变量”窗口的屏幕截图,其中显示了调试时局部变量的当前值。

oper 的值为 47 “/”,结果为 0,x 为 10,y 为 0。

还可以将鼠标悬停在代码本身中的变量上,以查看其当前暂停执行的当前值。 首先单击编辑器窗口,确保编辑器窗口处于焦点。

演示在将鼠标悬停在变量 y 上时出现的工具提示的视频。它显示 y 的当前值,即 0。

继续调试

  1. 左侧的黄色箭头显示当前执行点。 当前行调用 Calculate,因此按 F11步执行 函数,这会将你放入函数的 Calculate 正文中。 请谨慎使用步入功能,因为它会步入您所在行上的任何函数,包括标准库函数。 可以探索标准库,但你可能更有兴趣专注于你自己的代码而不是库代码。

  2. 现在,执行点位于函数的 Calculate 开头,请按 F10 移动到程序执行中的下一行。 F10 也称为 步过。 可以使用单步跳过逐行执行,而无需深入了解行中每个部分发生的情况的详细信息。 一般情况下,应使用 “单步跳过” 而不是 “单步进入”,除非你想更深入地了解从别处调用的代码(就像你为进入 Calculate 的主体所做的那样)。

  3. 继续使用 F10单步跳过 每行,直到返回到另一个文件中的 main() 函数,并在 cout 行停下。

    程序正在执行预期功能:它取第一个数字,并将其除以第二个数字。 在cout行上,将鼠标悬停在result变量上,或在“自动”窗口中查看result。 其值为 inf,它看起来不对。

    调试计算器的屏幕截图。

    调试器中的当前语句是 cout <<“Result is: ” << result << endl;在“自动”窗口中,结果为 inf。

    我们来修复它。 该 cout 行输出存储 result的任何值,因此使用 F10 再向前一行时,控制台窗口会显示:

    Visual Studio 调试控制台的屏幕截图,显示了零除操作的结果。

    应用输出:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5-0。 应用输出:结果为:5。 用户输入了 10/0。 应用输出:结果为:inf

    此结果是由于除以零未定义,因此程序无法为请求的运算提供数值答案。

修复“除以零”错误

让我们更优雅地处理零除问题,以便用户更容易理解问题。

  1. CalculatorTutorial.cpp中进行以下更改。 (由于调试器功能称为 “编辑并继续”,因此你可以在编辑时使程序保持运行状态。 更改是添加以下ifcin >> x >> oper >> y;语句,以检查除法是否为零,并在发生时向用户输出消息。 否则,结果将被打印出来:

    // CalculatorTutorial.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    #include <iostream>
    #include "Calculator.h"
    
    using namespace std;
    
    int main()
    {
        double x = 0.0;
        double y = 0.0;
        double result = 0.0;
        char oper = '+';
    
        cout << "Calculator Console Application" << endl << endl;
        cout << "Please enter the operation to perform. Format: a+b | a-b | a*b | a/b" << endl;
    
        Calculator c;
        while (true)
        {
            cin >> x >> oper >> y;
            if (oper == '/' && y == 0)
            {
                cout << "Division by 0 exception" << endl;
                continue;
            }
            else
            {
                result = c.Calculate(x, oper, y);
            }
            cout << "Result is: " << result << endl;
        }
    
        return 0;
    }
    
  2. F5 一次。 程序执行将继续,直到必须暂停才能请求用户输入。 再次输入 10 / 0 。 现在,打印了一条更有用的消息。 程序请求用户提供更多输入,程序继续正常运行。

    调试控制台的视频,显示代码更改后的最终结果。输入 10 / 0,程序显示“除以 0 例外”。

    注释

    在调试模式下编辑代码时,有代码变得陈旧的风险。 当调试器仍在运行旧代码,但尚未使用更改对其进行更新时,将发生这种情况。 调试器会弹出一个对话框,以在发生这种情况时通知你。 有时,可能需要按 F5 刷新正在执行的代码。 具体而言,如果在函数内部执行点发生更改,请退出该函数,然后再次返回该函数以获取更新的代码。 如果由于某种原因不起作用,并且看到错误消息,可以通过单击 IDE 顶部菜单下的工具栏中的红色方块来停止调试,然后通过输入 F5 或选择工具栏上停止按钮旁边的绿色“播放”箭头来重新开始调试。

    编辑并继续可能失败的另一个原因是需要转到主菜单并选择 “工具>选项>调试>常规 ”,并确保选中 “要求源文件与原始版本完全匹配 ”。

    了解“运行”和“调试”快捷方式

    • F5调试>启动调试,将启动一个调试会话(如果尚未处于活动状态),并运行程序,直到命中断点或程序需要用户输入。 如果不需要用户输入,并且没有可用的断点可供命中,程序将终止,当程序完成运行时,控制台窗口将自行关闭。 如果程序输出到控制台,请使用 Ctrl+F5 或设置断点,然后按 F5 使窗口保持打开状态。
    • Ctrl+F5调试>无调试启动,运行应用程序而不进入调试模式。 这比调试要快一些,程序完成执行后控制台窗口将保持打开状态。
    • F10,也称为“步过”,允许你逐行执行代码,并直观地观察代码的运行方式以及每个执行步骤中的变量值。
    • F11(称为 “步入”)的工作方式类似于 “单步执行”,只是它进入执行行中调用的任何函数。 例如,如果正在执行的行调用函数,请按 F11 将指针移到函数的正文中,以便可以按照函数的代码运行,然后再返回到开始的行。 按 F10 跳过函数调用,直接移到下一行; 函数调用仍然会执行,但程序不会暂停来展示执行过程。

关闭应用

  • 如果仍在运行,请关闭控制台窗口以停止计算器应用。

完成的应用

祝贺! 你已完成计算器应用的代码,并在 Visual Studio 中生成和调试它。

后续步骤

详细了解 Visual Studio for C++