C++程序员通常的起点是一个在命令行上运行的“Hello, world!” 应用程序。 从本文开始,然后转到更具挑战性的内容:计算器应用。
先决条件
- 已在您的计算机上安装并运行带有C++桌面开发工作负载的Visual Studio。 若要安装它,请参阅 Visual Studio 中的“安装C++支持”。
- 本教程演示了一项称为“编辑并继续”的功能,使你可以在应用运行时更改代码。 若要启用编辑并继续,请在主菜单中选择“ 工具>选项>调试>常规 ”,并确保选中 “要求源文件与原始版本完全匹配 ”。
创建应用项目
Visual Studio 使用 项目 来组织应用的代码,以及用于组织一个或多个项目 的解决方案 。 项目包含用于生成应用的所有选项、配置和规则。 它还管理所有项目文件和任何外部文件之间的关系。 若要创建应用,请先创建新的项目和解决方案。
启动 Visual Studio--“Visual Studio 开始”对话框随即出现。 选择“ 创建新项目 ”以开始。
该对话框具有克隆存储库、打开项目或解决方案、打开本地文件夹和创建新项目的选项。
在“ 创建新项目 ”对话框中,将语言下拉列表设置为 C++,将平台下拉列表设置为 Windows,从项目类型列表中选择 控制台应用 ,然后选择“ 下一步”。
语言下拉列表设置为C++,平台下拉列表设置为 Windows,项目类型(如空项目、控制台应用、CMake 项目、Windows 桌面向导等)显示在项目类型列表中。
重要
请确保选择 控制台应用 模板C++版本。 它具有 C++、 Windows 和 控制台 标记,图标在角处具有“++”。
在“ 配置新项目 ”对话框中,选择 “项目名称 ”文本框,将新项目命名为 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 直接创建的应用。
若要生成项目,请从“生成”菜单中选择“生成解决方案”。 输出 窗口显示构建过程的结果。
若要运行代码,请在菜单栏上选择 调试>不带调试启动 (Ctrl+F5)。
此时会打开控制台窗口,应用在其中运行。
在 Visual Studio 中启动控制台应用时,它会运行代码,然后打印“按任意键关闭此窗口。 . “为你提供了查看输出的机会。”
祝贺! 已在 Visual Studio 中创建第一个“Hello, world!” 控制台应用!
按键关闭控制台窗口并返回到 Visual Studio。
现在,你拥有在每次更改后生成和运行应用的工具,以验证代码是否仍按预期工作。 稍后,我们将向你展示如何调试它(如果没有)。
编辑代码
现在,让我们将此模板中的代码修改为计算器应用。
将文件的内容
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()
中访问所有代码才能使用。
- 该
若要保存文件,请按 Ctrl+S,或在菜单栏下的工具栏中选择软盘图标。
若要运行应用程序,请按 Ctrl+F5 或转到 “调试 ”菜单,然后选择“ 在没有调试的情况下启动”。 应会看到如下所示的控制台窗口。
完成后关闭控制台窗口。
添加代码以执行一些数学运算
类就像是用来定义对象功能的蓝图。 在这种情况下,我们将定义一个计算器类来包含数学逻辑。
添加 Calculator 类
转到 “项目” 菜单,然后选择“ 添加类”。 在 “类名 ”编辑框中,输入 计算器。 选择“确定”。
类名字段包含文本计算器。 .h 文件字段包含 Calculator.h。 .cpp文件字段包含Calculator.cpp。 基类字段为空。 内联选项和托管选项处于未选中状态。
将两个新文件添加到项目中。 若要同时保存所有已更改的文件,请按 Ctrl+Shift+S。 它是 文件>全部保存的键盘快捷方式。 还有一个工具栏按钮用于 “全部保存”,这是两个软盘的图标,位于 “保存 ”按钮旁边。 通常,最好经常执行 “全部保存 ”,因此不会错过保存任何更改。
“添加类”向导创建
.h
和.cpp
具有与类同名的文件。 可以在 “解决方案资源管理器” 窗口中看到项目文件的完整列表,该列表显示在 IDE 的一侧。 如果窗口不可见,请通过 “视图>解决方案资源管理器”从菜单栏中打开它。计算器教程项目具有包含 Calculator.h 的头文件节点。 源文件节点包含Calculator.cpp和CalculatorTutorial.cpp。 引用、外部依赖项和资源文件的节点可见,但已关闭。
可以通过在 “解决方案资源管理器” 窗口中双击该文件来打开文件。 双击
Calculator.h
将其打开。将
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
类。
- 此代码声明一个名为的新函数,该函数
绿色波浪线会出现在
Calculate
下方,因为虽然函数Calculate
已声明,但未定义。 将鼠标悬停在Calculate
,点击螺丝刀图标上的向下箭头,然后选择在Calculator.cpp
中创建“计算”的定义。此代码将添加到
Calculator.cpp
:函数的定义是:double Calculator::Calculate(double x, char oper, double y) { return 0.0; }
目前,它只返回 0.0。 让我们改变这点。
切换到
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
调用类成员函数
在
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()
可见。 - 变量
x
、y
变量oper
和result
声明分别存储第一个数字、第二个数字、运算符和最终结果。 最好给他们一些初始值以避免未定义的行为,这就是此处执行的作。 - 该
Calculator c;
行声明一c
个名为类实例Calculator
的对象。 类本身只是计算器工作原理的蓝图;该对象是执行数学运算的特定计算器。 - 该
while (true)
语句是一个循环。 只要循环中的条件()
为 true,循环中的代码将反复执行。 由于条件只是列为true
条件,因此始终为 true,因此循环将永远运行。 若要关闭程序,用户必须手动关闭控制台窗口。 否则,程序将始终等待新输入。 - 关键字
cin
接受来自用户的输入。 输入流足够智能,可以处理控制台窗口中输入的文本行,并按顺序将其放置在列出的每个变量中。 - 表达式
c.Calculate(x, oper, y);
调用Calculate
前面定义的函数,并提供输入的输入值和请求的作。 然后,该函数返回一个存储在result
中的数字。 - 最后,
result
打印到控制台,用户会看到计算结果。
- 由于C++程序始终从函数开始
再次生成并测试代码
现在再次测试程序,以确保一切正常工作。
按 Ctrl+F5 重新生成并启动应用。
Enter
5+5
,然后按 Enter。 验证结果是否为 10。应用输出消息:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5+5。 应用输出:5+5 的结果为:10
通过关闭控制台窗口来停止程序。
调试应用
由于用户可以自由地在控制台窗口中键入任何内容,因此请确保计算器处理意外输入。 我们来调试程序,而不是运行程序,以便我们可以检查它正在执行分步作的内容。
在调试器中运行应用
在行
CalcuatorTutorial.cpp
中设置断点:result = c.Calculate(x, oper, y);
若要设置断点,请单击编辑器窗口左边缘的灰色垂直栏中的线条旁边,以便出现红点。现在,当我们调试程序时,执行将暂停在该行。 我们已经大致了解了该计划适用于简单情况。 由于我们不想在每次调用
Calculate()
时暂停执行,因此让我们设置断点条件。右键单击表示断点的红点,然后选择“ 条件”。 在条件的编辑框中,输入
(y == 0) && (oper == '/')
。 选择 “关闭 ”按钮以保存断点条件。断点位于行上:result = c dot Calculate (x, oper, y)。 “条件...”选中“条件”选项。 “条件”下拉列表设置为“条件表达式”。 条件下拉列表设置为“为真”。 条件设置为 y == 0 && oper == '/'。
现在,当应用尝试除以 0 时,执行会在断点处暂停。
若要调试程序,请按 F5,或选择具有绿色箭头图标的 本地 Windows 调试器调试器 工具栏按钮。 在控制台应用中,如果输入类似于“5 - 0”的内容,程序的行为正常并持续运行。 但是,如果键入“10/0”,它会在断点处暂停。 可以在运算符和数字之间放置任意数量的空格:
cin
足够智能,可以适当地分析输入。
调试器中的有用窗口
调试代码时,你可能会注意到会出现一些新窗口。 这些窗口可以帮助你的调试体验。 查看 “自动” 窗口。 “ 自动” 窗口显示变量的当前值,这些变量在当前行之前和前面至少使用了三行。 如果未看到 “自动” 窗口,请从主菜单中选择 “调试>Windows>自动”。
oper 的值为 47 “/”,结果为 5,x 为 10,y 为 0。
若要查看该函数中的所有变量,请切换到 “局部变量 ”窗口。 由于这是一个小函数,因此“自动”和“局部变量”窗口显示相同的变量。 但是,你可以在调试时修改“局部变量”窗口中这些变量的值,以查看它们对程序的影响。 在这种情况下,我们不干涉它们。 通过选择“自动”窗口底部的“局部变量”或从主菜单中选择“调试>Windows>局部变量”,打开“局部变量”窗口。
oper 的值为 47 “/”,结果为 0,x 为 10,y 为 0。
还可以将鼠标悬停在代码中的变量上,以查看当前暂停执行时的当前值。 首先单击编辑器窗口,确保编辑器窗口处于焦点。
继续调试
左侧的黄色箭头显示当前执行点。 当前行调用
Calculate
,因此按 F11 单步进入函数。 现在,你正在函数正文Calculate
中执行代码。 请谨慎使用步入功能,因为它会步入您所在行上的任何函数,包括标准库函数。 可以探索标准库,但你可能更有兴趣专注于你自己的代码而不是库代码。现在,执行点位于函数的
Calculate
开头,请按 F10 移动到程序执行中的下一行。 F10 也称为 步过。 可以使用单步跳过逐行执行,而无需深入了解行中每个部分发生的情况的详细信息。 一般情况下,应使用 “单步跳过” 而不是 “单步执行” ,除非你想深入查看从其他地方调用的代码(正如你为到达Calculate
的主体所做的)。继续使用 F10单步跳过 每行,直到返回到另一个文件中的
main()
函数,并在cout
行停下。程序正在执行预期功能:它取第一个数字,并将其除以第二个数字。 在
cout
行上,将鼠标悬停在result
变量上,或在“自动”窗口中查看result
。 其值为inf
,它看起来不对。调试器中的当前语句是 cout <<“Result is: ” << result << endl;在“自动”窗口中,结果为 inf。
我们来修复它。 该
cout
行输出存储result
的任何值,因此使用 F10 再向前一行时,控制台窗口会显示:应用输出:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5-0。 应用输出:结果为:5。 用户输入了 10/0。 应用输出:结果为:inf
此结果是由于除以零未定义,因此程序无法为请求的运算提供数值答案。
修复“除以零”错误
让我们更优雅地处理零除问题,以便用户更容易理解问题。
在
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; }
按 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 存储库。 操作方法如下:
在 Visual Studio 右下角的状态栏中,选择“ 添加到源代码管理”,然后选择 “Git”。
在“ 创建 Git 存储库 ”对话框中,登录到 GitHub。
存储库名称根据文件夹位置自动填充。 默认情况下,新存储库是专用的,这意味着你是唯一可以访问它的人。
小窍门
无论存储库是公共的还是专用的,最好有一个安全存储在 GitHub 上的代码的远程备份。 即使你未与团队合作,远程存储库也会让你从任何计算机获得代码。
选择“创建并推送”。
创建存储库后,状态详细信息将显示在状态栏中。
带有箭头的第一个图标显示当前分支中的传出/传入提交数。 可以使用此图标来拉取任何传入提交或推送任何传出提交。 还可以选择先查看这些提交。 为此,请选择图标,然后选择“ 查看传出/传入”。
第二个带有铅笔的图标显示代码未提交的更改数。 可以选择此图标,在 Git 更改 窗口中查看这些更改。
若要详细了解如何将 Git 与应用配合使用,请参阅 Visual Studio 版本控制文档。
完成的应用
祝贺! 你完成了计算器应用的代码,生成并调试了它,并将其添加到存储库,全部在 Visual Studio 中。
后续步骤
C++程序员通常的起点是一个在命令行上运行的“Hello, world!” 应用程序。 从本文开始,然后转到更具挑战性的内容:计算器应用。
先决条件
- 已在您的计算机上安装并运行带有C++桌面开发工作负载的Visual Studio。 若要安装它,请参阅 Visual Studio 中的“安装C++支持”。
创建应用项目
Visual Studio 使用 项目 来组织应用的代码,以及用于组织一个或多个项目 的解决方案 。 项目包含用于生成应用的所有选项、配置和规则。 它还管理所有项目文件和任何外部文件之间的关系。 若要创建应用,请先创建新的项目和解决方案。
在 Visual Studio 的菜单栏上,选择“ 文件>新建>项目”。 此时会打开 “新建项目” 窗口。
在左侧栏中,确保选中 “视觉对象C++ ”。 在中心内,选择 “控制台应用”。
在底部的“ 名称 ”文本框中,将新项目命名为 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 直接创建的应用。
若要生成项目,请从“生成”菜单中选择“生成解决方案”。 输出 窗口显示构建过程的结果。
若要运行代码,请在菜单栏上选择 “调试”, 开始而不调试 (Ctrl+F5)。
此时会打开控制台窗口,应用在其中运行。
在 Visual Studio 中启动控制台应用时,它会运行代码,然后打印
Press any key to close this window . . .
,让你有机会查看输出。祝贺! 已在 Visual Studio 中创建第一个“Hello, world!” 控制台应用!
按键关闭控制台窗口并返回到 Visual Studio。
现在,你拥有在每次更改后生成和运行应用的工具,以验证代码是否仍按预期工作。 稍后,我们将向你展示如何调试它(如果没有)。
编辑代码
现在,让我们将此模板中的代码转换为计算器应用。
将文件的内容
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()
中访问所有代码才能使用。
- 该
若要保存文件,请按 Ctrl+S,或在菜单栏下的工具栏中选择软盘图标。
若要运行应用程序,请按 Ctrl+F5 或转到 “调试 ”菜单,然后选择“ 在没有调试的情况下启动”。 如果收到显示 “此项目已过期”的弹出窗口,则可以再次选择“ 不显示此对话框”,然后选择“ 是 ”以生成应用程序。 应会看到如下所示的控制台窗口:
控制台应用显示输出,即:计算器控制台应用程序。 请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 进程以代码 0 退出,并显示一条消息:要在调试停止时自动关闭控制台,请启用“工具 > 选项 > 调试 > 调试停止时自动关闭控制台”。 最后,屏幕上会显示一条消息,提示您按任意键关闭此窗口。
完成后关闭控制台窗口。
添加代码以执行一些数学运算
类就像是用来定义对象功能的蓝图。 在这种情况下,我们将定义一个计算器类来包含数学逻辑。
添加 Calculator 类
转到 “项目” 菜单,然后选择“ 添加类”。 在 “类名 ”编辑框中,输入 计算器。 选择“确定”。
类名字段包含文本计算器。 .h 文件字段包含 Calculator.h。 .cpp文件字段包含Calculator.cpp。 基类字段为空。 内联选项和托管选项处于未选中状态。
类就像是用来定义对象功能的蓝图。 在本例中,我们定义计算器及其工作原理。
将两个新文件添加到项目中。 若要同时保存所有已更改的文件,请按 Ctrl+Shift+S。 它是 文件>全部保存的键盘快捷方式。 还有一个工具栏按钮用于 “全部保存”,这是两个软盘的图标,位于 “保存 ”按钮旁边。 通常,最好经常执行 “全部保存 ”,因此在保存时不会错过任何文件。
“添加类”向导创建
.h
和.cpp
具有与类同名的文件。 可以在 “解决方案资源管理器” 窗口中看到项目文件的完整列表,该列表显示在 IDE 的一侧。 如果 解决方案资源管理器 不可见,请从菜单栏中打开它:选择 “查看>解决方案资源管理器”。计算器教程项目有一个头文件节点,其中包含 Calculator.h、stdafx.h 和 targetver.h。 源文件节点包含Calculator.cpp、CalculatorTutorial.cpp和stdafx.cpp。 引用、外部依赖项和资源文件的节点可见,但已关闭。
可以通过在 “解决方案资源管理器” 窗口中双击该文件来打开文件。 双击
Calculator.h
将其打开。将
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
类。
- 此代码声明一个名为的新函数,该函数
绿色波浪线会出现在
Calculate
下方,因为虽然函数Calculate
已声明,但未定义。 将鼠标悬停在Calculate
灯泡上,单击灯泡上的向下箭头,然后在其中Calculator.cpp
选择“计算”的创建定义。 此时会显示一个弹出窗口,可让你查看另一个文件中所做的代码更改。 代码已添加到Calculator.cpp
.目前,它只返回 0.0。 让我们改变这点。 按 Esc 关闭弹出窗口,然后选择 “是 ”保存更改。
切换到
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 类成员函数
在
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()
可见。 - 变量
x
、y
变量oper
和result
声明分别存储第一个数字、第二个数字、运算符和最终结果。 最好给他们指定一些初始值以避免未定义的行为,这就是在此处所采取的步骤。 - 该
Calculator c;
行声明一个名为c
的对象,该对象是Calculator
类的实例。 类本身只是计算器工作原理的蓝图;该对象是执行数学运算的特定计算器。 - 该
while (true)
语句是一个循环。 只要循环中的条件()
为 true,循环中的代码就反复执行。 由于条件只是列为true
条件,因此始终为 true,因此循环将永远运行。 若要关闭程序,用户必须手动关闭控制台窗口。 否则,程序将始终等待新输入。 - 关键字
cin
接受来自用户的输入。 输入流足够智能,可以处理控制台窗口中输入的文本行,并按顺序将其放置在列出的每个变量中。 - 表达式
c.Calculate(x, oper, y);
调用前面定义的Calculate
函数,并提供输入值和请求的操作。 然后,该函数返回一个存储在result
中的数字。 - 最后,
result
打印到控制台,用户会看到计算结果。
- 由于C++程序始终从函数开始
再次生成并测试代码
再次测试程序,以确保一切正常工作。
按 Ctrl+F5 重新生成并启动应用。
Enter
5+5
,然后按 Enter。 验证结果是否为 10。通过关闭控制台窗口来停止程序。
调试应用
由于用户可以自由地在控制台窗口中键入任何内容,因此请确保计算器处理意外输入。 我们这次来调试而不是运行程序,这样我们可以逐步检查它的执行过程。
在调试器中运行应用
在
CalcuatorTutorial.cpp
中的result = c.Calculate(x, oper, y);
行上设置断点。 若要设置断点,请单击编辑器窗口左边缘的灰色垂直栏中的线条旁边,以便出现红点。现在,每次调试程序时,它都会始终在该行暂停执行。 我们已经大致了解了该计划适用于简单情况。 由于我们不想每次都暂停执行,因此我们将设置有条件断点。
右键单击表示断点的红点,然后选择“ 条件”。 在条件的编辑框中,输入
(y == 0) && (oper == '/')
。 完成后选择 “关闭 ”按钮以保存断点条件。断点位于行上:result = c dot Calculate (x, oper, y)。 “条件...”选中“条件”选项。 “条件”下拉列表设置为“条件表达式”。 条件下拉列表设置为“为真”。 条件设置为 y == 0 && oper == '/'。
如果尝试除以 0,则执行将在断点处暂停。
若要调试程序,请按 F5,或选择具有绿色箭头图标的 本地 Windows 调试器 工具栏按钮。 在控制台应用中,如果输入类似于“5 - 0”的内容,程序的行为正常并持续运行。 但是,如果键入“10/0”,它会在断点处暂停。 甚至可以在运算符和数字之间放置任意数量的空格;
cin
足够聪明,可以适当地分析输入。显示程序在条件断点处暂停执行的视频。
用户输入“5 - 0”。 应用输出:结果为 5。 然后,用户输入 10/0,由于满足了条件断点的条件,程序执行停止在这一行:result = c.Calculate(x,oper,y):
调试器中的有用窗口
调试代码时,你可能会注意到会出现一些新窗口。 这些窗口可以帮助你的调试体验。 查看 “自动” 窗口。 “ 自动” 窗口显示变量的当前值,这些变量在当前行之前和前面至少使用了三行。 如果未看到 “自动” 窗口,请从主菜单中选择 “调试>Windows>自动”。
oper 的值为 47 “/”,结果为 5,x 为 10,y 为 0。
若要查看该函数中的所有变量,请切换到 “局部变量 ”窗口。 由于这是一个小函数,因此“自动”和“局部变量”窗口显示相同的变量。 但是,你可以在调试时修改这些变量的值,以查看它们对程序的影响。 在这种情况下,我们不干涉它们。 通过选择“自动”窗口底部的“局部变量”或从主菜单中选择“调试>Windows>局部变量”,打开“局部变量”窗口。
oper 的值为 47 “/”,结果为 0,x 为 10,y 为 0。
还可以将鼠标悬停在代码本身中的变量上,以查看其当前暂停执行的当前值。 首先单击编辑器窗口,确保编辑器窗口处于焦点。
继续调试
左侧的黄色箭头显示当前执行点。 当前行调用
Calculate
,因此按 F11 单 步执行 函数,这会将你放入函数的Calculate
正文中。 请谨慎使用步入功能,因为它会步入您所在行上的任何函数,包括标准库函数。 可以探索标准库,但你可能更有兴趣专注于你自己的代码而不是库代码。现在,执行点位于函数的
Calculate
开头,请按 F10 移动到程序执行中的下一行。 F10 也称为 步过。 可以使用单步跳过逐行执行,而无需深入了解行中每个部分发生的情况的详细信息。 一般情况下,应使用 “单步跳过” 而不是 “单步进入”,除非你想更深入地了解从别处调用的代码(就像你为进入Calculate
的主体所做的那样)。继续使用 F10单步跳过 每行,直到返回到另一个文件中的
main()
函数,并在cout
行停下。程序正在执行预期功能:它取第一个数字,并将其除以第二个数字。 在
cout
行上,将鼠标悬停在result
变量上,或在“自动”窗口中查看result
。 其值为inf
,它看起来不对。调试器中的当前语句是 cout <<“Result is: ” << result << endl;在“自动”窗口中,结果为 inf。
我们来修复它。 该
cout
行输出存储result
的任何值,因此使用 F10 再向前一行时,控制台窗口会显示:应用输出:请输入要执行的操作。 格式:a+b |a-b |a*b |a/b. 用户输入了 5-0。 应用输出:结果为:5。 用户输入了 10/0。 应用输出:结果为:inf
此结果是由于除以零未定义,因此程序无法为请求的运算提供数值答案。
修复“除以零”错误
让我们更优雅地处理零除问题,以便用户更容易理解问题。
在
CalculatorTutorial.cpp
中进行以下更改。 (由于调试器功能称为 “编辑并继续”,因此你可以在编辑时使程序保持运行状态。 更改是添加以下if
cin >> 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; }
按 F5 一次。 程序执行将继续,直到必须暂停才能请求用户输入。 再次输入
10 / 0
。 现在,打印了一条更有用的消息。 程序请求用户提供更多输入,程序继续正常运行。注释
在调试模式下编辑代码时,有代码变得陈旧的风险。 当调试器仍在运行旧代码,但尚未使用更改对其进行更新时,将发生这种情况。 调试器会弹出一个对话框,以在发生这种情况时通知你。 有时,可能需要按 F5 刷新正在执行的代码。 具体而言,如果在函数内部执行点发生更改,请退出该函数,然后再次返回该函数以获取更新的代码。 如果由于某种原因不起作用,并且看到错误消息,可以通过单击 IDE 顶部菜单下的工具栏中的红色方块来停止调试,然后通过输入 F5 或选择工具栏上停止按钮旁边的绿色“播放”箭头来重新开始调试。
编辑并继续可能失败的另一个原因是需要转到主菜单并选择 “工具>选项>调试>常规 ”,并确保选中 “要求源文件与原始版本完全匹配 ”。
了解“运行”和“调试”快捷方式
- F5 或 调试>启动调试,将启动一个调试会话(如果尚未处于活动状态),并运行程序,直到命中断点或程序需要用户输入。 如果不需要用户输入,并且没有可用的断点可供命中,程序将终止,当程序完成运行时,控制台窗口将自行关闭。 如果程序输出到控制台,请使用 Ctrl+F5 或设置断点,然后按 F5 使窗口保持打开状态。
- Ctrl+F5 或 调试>无调试启动,运行应用程序而不进入调试模式。 这比调试要快一些,程序完成执行后控制台窗口将保持打开状态。
- F10,也称为“步过”,允许你逐行执行代码,并直观地观察代码的运行方式以及每个执行步骤中的变量值。
- F11(称为 “步入”)的工作方式类似于 “单步执行”,只是它进入执行行中调用的任何函数。 例如,如果正在执行的行调用函数,请按 F11 将指针移到函数的正文中,以便可以按照函数的代码运行,然后再返回到开始的行。 按 F10 跳过函数调用,直接移到下一行; 函数调用仍然会执行,但程序不会暂停来展示执行过程。
关闭应用
- 如果仍在运行,请关闭控制台窗口以停止计算器应用。
完成的应用
祝贺! 你已完成计算器应用的代码,并在 Visual Studio 中生成和调试它。