之前的课程介绍了许多术语和概念,我们将在几乎所有程序中使用这些知识。在这节课中,我们将通过一个简单的程序,将这些知识整合到一起。 乘以2 首先,我们来创建一个程序,要求用户输入一个整数,等待他们输入一个整数,然后告诉他们这个数字的两倍是多少。程序应该产生以下输出(假设我输入了4): 输入一个整数:4 那个数字的两倍是:8
我们如何来解决这个问题呢?分步骤进行。
最佳实践
新程序员通常试图一次性编写整个程序,然后在程序产生大量错误时感到不知所措。更好的策略是一次添加一个部分,确保它能够编译,然后测试它。当你确定它工作正常后,再继续下一个部分。
我们将在这里采用这种策略。在我们完成每个步骤时,将每个程序(不要复制/粘贴)输入到你的代码编辑器中,编译并运行它。 首先,创建一个新的控制台项目。
现在让我们从一些基本的框架开始。我们知道我们将需要一个main()函数(因为所有的C++程序都必须有一个),所以如果你的IDE在创建新项目时没有创建一个空白的,让我们创建一个:
int main()
{
return 0;
}
我们知道我们将需要向控制台输出文本,并从用户的键盘获取文本,所以我们需要包含iostream以访问std::cout和std::cin。
#include <iostream>
int main()
{
return 0;
}
现在让我们告诉用户我们需要他们输入一个整数:
#include <iostream>
int main()
{
std::cout << "Enter an integer: ";
return 0;
}
此时,你的程序应该产生以下结果: 输入一个整数:
然后程序终止。
获取用户输入
接下来,我们将获取用户的输入。我们将使用std::cin和操作符»来获取用户的输入。但我们还需要定义一个变量来存储稍后使用的输入。
#include <iostream>
int main() // 注意:这个程序在某处有一个错误
{
std::cout << "Enter an integer: ";
int num{ }; // 定义变量num为一个整数变量
std::cin << num; // 从用户的键盘获取整数值
return 0;
}
编译错误分析
是时候编译我们的更改了……然后… 哎呀!这是作者在Visual Studio 2017上得到的结果:
1>------ 构建开始:项目:Double, 配置:Release Win32 ------
1>Double.cpp
1>c:\vcprojects\double\double.cpp(8): error C2678: binary '<<': no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
1>c:\vcprojects\double\double.cpp: note: could be 'built-in C++ operator<<(bool, int)'
1>c:\vcprojects\double\double.cpp: note: while trying to match the argument list '(std::istream, int)'
1>构建项目 "Double.vcxproj" -- 失败。
========== 构建:0成功,1失败,0更新,0跳过 ==========
错误定位与修正
我们遇到了编译错误! 首先,由于程序在我们进行最新更新之前编译通过了,现在编译不通过,错误一定在我们刚刚添加的代码中(第7行和第8行)。这大大减少了我们需要扫描的代码量以找到错误。第7行非常直接(只是一个变量定义),所以错误可能不在那里。这让我们认为第8行可能是罪魁祸首。 其次,这个错误消息不是很容易读懂。但让我们挑出一些关键元素:编译器告诉我们它在第8行遇到了错误。这意味着实际错误可能在第8行,或者可能是前一行,这加强了我们之前的评估。接下来,编译器告诉你它找不到一个’«‘操作符,其左手操作数类型为std::istream(std::cin的类型)。换句话说,操作符«不知道如何处理std::cin,所以错误可能是我们使用std::cin或操作符«的方式。
现在看到错误了吗?如果没有,花点时间看看你是否能发现它。
修正后的代码
以下是包含修正代码的程序:
#include <iostream>
int main()
{
std::cout << "Enter an integer: ";
int num{ };
std::cin >> num; // std::cin使用操作符>>,而不是操作符<<!
return 0;
}
现在程序将编译,我们可以测试它。程序将等待你输入一个数字,所以让我们输入4。输出应该如下所示: 输入一个整数:4
完成程序功能
差不多了!最后一步是将数字翻倍。 一旦我们完成这最后一步,我们的程序将编译并成功运行,产生所需的输出。
我们(至少)有3种方法可以做到这一点。让我们从最差到最好。
方案一:直接修改变量值
不好的解决方案
#include <iostream>
// 最差版本
int main()
{
std::cout << "Enter an integer: ";
int num{ };
std::cin >> num;
num = num * 2; // 将num的值翻倍,然后将该值赋回num
std::cout << "Double that number is: " << num << '\n';
return 0;
}
在这个解决方案中,我们使用一个表达式将num乘以2,然后将该值赋回num。从那时起,num将包含我们的翻倍数字。 为什么这是一个不好的解决方案:
在赋值语句之前,num包含用户的输入。赋值之后,它包含一个不同的值。这很令人困惑。 我们通过给输入变量赋新值覆盖了用户的输入,所以如果我们想扩展我们的程序以稍后用该输入值做其他事情(例如,将用户的输入乘以三),它已经被丢失了。
方案二:使用新变量
大部分好的解决方案
#include <iostream>
// 较差的版本
int main()
{
std::cout << "Enter an integer: ";
int num{ };
std::cin >> num;
int doublenum{ num * 2 }; // 定义一个新变量并用num * 2初始化它
std::cout << "Double that number is: " << doublenum << '\n'; // 然后在这里打印该变量的值
return 0;
}
这个解决方案非常简单明了,解决了最差解决方案中遇到的两个问题。 这里的主要缺点是我们定义了一个新变量(这增加了复杂性)来存储我们只使用一次的值。我们可以做得更好。
方案三:直接在输出中计算
首选解决方案
#include <iostream>
// 首选版本
int main()
{
std::cout << "Enter an integer: ";
int num{ };
std::cin >> num;
std::cout << "Double that number is: " << num * 2 << '\n'; // 使用表达式在我们要打印的地方将num * 2
return 0;
}
这是这组解决方案中的首选。当std::cout执行时,表达式num * 2将被评估,结果将是num值的两倍。该值将被打印出来。num本身的值不会被更改,所以我们稍后如果需要可以再次使用它。 这个版本是我们的参考解决方案。
编程实践建议
编程的第一个和主要目标是使你的程序工作。一个不工作的程序无论写得多好都是无用的。 然而,我喜欢一句谚语:“你必须写一次程序,才知道你第一次应该怎么写它。“这表明最佳解决方案通常并不明显,我们对问题的第一个解决方案通常不如它们可能的那么好。 当我们专注于如何使我们的程序工作时,投入大量时间到我们甚至不知道是否会保留的代码中是没有意义的。所以我们走捷径。我们跳过错误处理和注释等事情。我们在解决方案中到处撒上调试代码,以帮助我们诊断问题和查找错误。我们边做边学——我们认为可能有效的事情最终并不有效,我们必须回头尝试另一种方法。 最终结果是,我们的初始解决方案通常结构不佳,不健壮(防错),不易读或不简洁。所以一旦你的程序工作了,你的工作实际上并没有完成(除非程序是一次性/废弃的)。下一步是清理你的代码。这涉及到移除(或注释掉)临时/调试代码,添加注释,处理错误情况,格式化你的代码,并确保遵循最佳实践。即使如此,你的程序可能也不及它可能的那么简单——也许有可以合并的冗余逻辑,或者可以合并的多个语句,或者不需要的变量,或者一千个其他可能简化的小事情。新程序员往往过于关注优化性能,而应该关注可维护性。 这些教程中提出的解决方案很少第一次就做得很好。相反,它们是持续改进的结果,直到找不到其他可以改进的地方。在许多情况下,读者仍然发现很多其他事情可以建议作为改进! 所有这些都是为了说:如果你/当你的解决方案没有直接从你的大脑中以奇妙的优化形式出现时,不要感到沮丧。那是正常的。编程中的完美是一个迭代过程(一个需要重复通过的过程)。
学习建议
还有一件事:你可能在想,“C++有如此多的规则和概念。我怎么才能记住所有这些东西?” 简短的回答是:你不需要。C++是一部分使用你所知道的,两部分查找如何做其余部分。 当你第一次阅读这个网站时,不要过于关注记忆具体内容,而更多地关注理解可能的东西。然后,当你需要在编写的程序中实现某件事时,你可以回到这里(或参考网站)并刷新自己如何做到这一点。