C++ 程序员通常从在命令行上运行的“Hello, world!”应用程序开始。 你将以本文为起点,逐步进阶,加深学习难度:计算器应用。

先决条件

1、在 Visual Studio 中安装“使用 C++ 的桌面开发”工作负载并在计算机上运行。 请参阅在 Visual Studio 中安装 C++ 支持,了解如何安装该工作负载。

2、本教程演示了“编辑并继续”这项功能,使用此功能,可以在应用运行时对代码进行更改。 若要启用“编辑并继续”,请在主菜单中选择“工具”>“选项”>“调试”>“常规”,并确保选中“要求源文件与原始版本完全匹配”。

创建应用项目

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

1、启动 Visual Studio - 将出现 Visual Studio 启动对话框。 选择“创建新项目”以开始使用。

1.jpg

2、在项目模板列表中,依次选择“控制台应用”、“下一步”。

2.jpg


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

3.jpg

将创建一个空的 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、若要生成项目,请从“生成”菜单选择“生成解决方案”。 “输出”窗口将显示生成过程的结果 。

4.jpg


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

5.jpg随即将打开控制台窗口,然后运行你的应用。

在 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 语句允许引用位于其他文件中的代码。 有时,文件名使用尖括号 (<>) 括起来;其他情况下,使用引号 (" ") 括起来。 通常,引用 C++ 标准库时使用尖括号,引用其他文件时使用引号。

using namespace std; 行提示编译器期望在此文件中使用 C++ 标准库中的内容。 如果没有这一行,库中的每个关键字都必须以 std:: 开头,以表示其范围。 例如,如果没有该行,则对 cout 的每个引用都必须写为 std::cout。 using 语句的使用是为了使代码看起来更干净。

cout 关键字用于在 C++ 中打印到标准输出。 << 运算符提示编译器将其右侧的任何内容发送到标准输出。

endl 关键字与 Enter 键类似;用于结束该行并将光标移动到下一行。 如果要执行相同的操作,最好在字符串中使用 \n(用 "" 包含),因为使用 endl 会始终刷新缓冲,进而可能影响程序的性能。 但是,由于这是一个非常小的应用,所以改为使用 endl 以提高可读性。

所有 C++ 语句都必须以分号结尾,所有 C++ 应用程序都必须包含 main() 函数。 该函数是程序开始运行时运行的函数。 若要使用所有代码,必须可从 main() 访问所有代码。

2、要保存文件,请按下 Ctrl+S,或者选择 IDE 顶部附近的“保存”图标,即菜单栏下工具栏中的软盘图标。

3、要运行该应用程序,请按“Ctrl+F5”或转到“调试”菜单,然后选择“启动但不调试”。 应会显示一个控制台窗口,其中显示代码中指定的文本。

4、完成后,请关闭控制台窗口。


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

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

添加 Calculator 类

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

6.jpg

这会向项目中添加两个新文件。 若要同时保存所有已更改的文件,请按“Ctrl+Shift+S” 。 这是“文件”>“全部保存”的键盘快捷方式 。 在“保存”按钮旁边还有一个用于“全部保存”的工具栏按钮,这是两个软盘的图标 。 一般来说,最好经常使用“全部保存”,这样你保存时就不会遗漏任何文件 。


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

6-1.jpg

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


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

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

了解代码

此代码声明了一个名为 Calculate 的新函数,我们将使用它来运行加法、减法、乘法和除法的数学运算。

C ++ 代码被组织成标头 (.h) (.h) 文件和源 (.cpp) 文件。 所有类型的编译器都支持其他几个文件扩展名,但这些是要了解的主要文件扩展名。 函数和变量通常在头文件中进行声明(即在头文件中指定名称和类型)和实现(或在源文件中指定定义) 。 若要访问在另一个文件中定义的代码,可以使用 #include "filename.h",其中 filename.h 是声明要使用的变量或函数的文件的名称。

最好根据代码的功能将代码组织到不同的文件中,方便稍后需要这些代码时能够轻易查找到。 在本例中,我们分别定义了 Calculator 类和包含 main() 函数的文件,但我们计划在 main() 中引用 Calculator 类。


3、Calculate 下方会出现绿色波浪线,因为尽管已声明 Calculate 函数,但并未定义该函数。 将鼠标悬停在 Calculate 上,单击显示的螺丝刀上的向下箭头,然后选择“在 Calculator.cpp 中创建 "Calculate" 定义”。

7.jpg

此代码将添加到 Calculator.cpp:

8.jpg目前,它只返回 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 关键字表示支持小数的数字类型。 因此,Calculator 可以处理十进制数学和整数数学。 要始终返回这样的数字,需要 Calculate 函数,因为代码的最开始是 double(这表示函数的返回类型),这就是为什么我们在默认情况下返回 0.0。

.h 文件声明函数“prototype”,它预先告诉编译器它需要什么参数,以及期望它返回什么样的返回类型。 .cpp 文件包含该函数的所有实现细节。

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


调用 Calculator 类的成员函数

按如下所示更新 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 语句。

声明了一些初始变量 x、y、oper 和 result,分别用于存储第一个数字、第二个数字、运算符和最终结果。 提供一些初始变量始终是最佳做法,这样可避免未定义的行为,此示例即是如此。

Calculator c; 行声明一个名为“c”的对象作为 Calculator 类的实例。 类本身只是计算器工作方式的蓝图;对象是进行数学运算的特定计算器。

while (true) 语句是一个循环。 只要 () 内的条件成立,循环内的代码就会一遍又一遍地执行。 由于条件简单地列为 true,它始终为 true,因此循环将永远运行。 若要关闭程序,用户必须手动关闭控制台窗口。 否则,程序始终等待新输入。

cin 关键字用于接受来自用户的输入。 假设用户输入符合所需规范,此输入流足够智能,可以处理在控制台窗口中输入的一行文本,并按顺序将其放入列出的每个变量中。 可以修改此行以接受不同类型的输入,例如,两个以上的数字,但还需要更新 Calculate() 函数来处理此问题。

c.Calculate(x, oper, y); 表达式调用前面定义的 Calculate 函数,并提供输入的输入值。 然后该函数返回一个存储在 result 中的数字。

最后,将 result 输出到控制台,以便用户查看计算结果。



再次生成和测试代码

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

1、按“Ctrl+F5”重建并启动应用 。

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

9.jpg


调试应用

由于用户可以自由地在控制台窗口中输入任何内容,因此请确保计算器会处理意外输入。 现在调试程序,而不运行程序,以便可以逐步检查程序所执行的每一项操作。

在调试器中运行应用

1、在 CalcuatorTutorial.cpp 中的 result = c.Calculate(x, oper, y); 行上设置断点。 若要设置断点,请在该行旁边编辑器窗口左边缘的灰色竖线上单击。 将显示一个红点。

9-1.jpg现在,当调试程序时,执行进程会暂停在该行。 我们已大概了解了该程序可用于简单案例。 由于不想每次调用 Calculate() 时都暂停执行,因此可以设置断点条件。


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

9-2.jpg

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


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

9-3.jpg


调试器中有用的窗口

调试代码时,你可能会注意到会出现一些新窗口。 你可借助这些窗口提高调试体验。 了解一下“自动”窗口 。 显示的“自动”窗口指示,在当前行之前,变量的当前值至少使用了三行 。

9-4.jpg

若要查看该函数的所有变量,请切换到“局部变量”窗口 。 可以在调试时修改这些变量的值,以查看它们对程序的影响。 在这种情况下,不必理会。

9-5.jpg

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

9-6.jpg


继续调试

1、左侧的黄色箭头表示当前的执行点。 当前行调用 Calculate,因此按 F11 以“单步执行”函数 。 现在,你就在 Calculate 函数的主体中执行代码。 请小心使用“单步执行”,因为它会单步执行你正在处理的行上的任何函数,包括标准库函数。 单步执行标准库没有问题,但你可能更想专注于你的代码而不是库代码。

2、现在执行点位于 Calculate 函数的开头,按 F10 移动到程序执行的下一行 。 F10 也称为“单步跳过” 。 可以使用“单步跳过”在行与行之间移动,而无需深入研究行的每个部分的详细信息 。 一般情况下,应使用“单步跳过”而不是“单步执行”,除非你希望深入研究从其他地方调用的代码(就像你访问 Calculate 的主体一样)。

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

程序在按预期执行操作:取第一个数字,然后除以第二个数字。 在 cout 行,将鼠标悬停在 result 变量上,或在“自动”窗口中查看 result 。 它的值 inf 看起来似乎不正确,因此我们来修复此错误。 cout 行只输出存储在 result 中的任何值,因此当使用 F10 向前再执行一行时,控制台窗口将显示以下内容 :

9-7.jpg出现这种结果是因为未定义除以零运算,因此程序无法给请求的运算提供数值解。


修复“被零除”错误

让我们更简洁地处理除数为零的情况,让用户可以更轻松地了解问题。

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 << "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。 现在,将输出更有用的信息。 用户被要求输入更多内容,程序继续正常执行。

备注

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


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

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

按 F5(或“调试”>“启动调试”)启动调试会话(如果尚未激活),并运行程序,直到到达断点或程序需要用户输入 。 如果不需要用户输入,也没有可用的断点,程序将终止,当程序运行结束时,控制台窗口将自动关闭。 如果要运行类似“Hello World”程序,请使用 Ctrl+F5 或在按下 F5 之前设置断点以保持窗口打开。

Ctrl+F5(或“调试”>“开始执行(不调试)”在不进入调试模式的情况下运行应用程序 。 此快捷方式比调试要略微快一些,并且在程序执行完成后控制台窗口仍保持打开状态。

F10(称为“单步跳过”步骤)可逐行迭代代码,并可视化代码的运行方式,以及执行每个步骤的变量值 。

F11(称为“单步执行”)的工作方式类似于“单步跳过”,只是它将单步执行在执行行上调用的任何函数 。 例如,如果正在执行的行调用了一个函数,按下 F11 可将指针移动到函数体中,这样就可以在返回开始的行之前遵循正在运行的函数代码 。 按 F10 可执行函数调用并移动到下一行;函数调用仍然会发生,但是程序不会暂停来显示它在做什么 。


关闭应用程序

如果它仍在运行,请关闭计算器应用的控制台窗口。