系统(“暂停”) ;-为什么是错误的?

有个问题我不太明白:

system("pause");命令被传授给新程序员,作为暂停程序并等待键盘输入继续的一种方法。然而,许多经验丰富的程序员似乎不赞成这样做,认为不应该在不同程度上这样做。

有些人说这是罚款使用。有人说只有当你被锁在房间里,没有人在看的时候才能使用。有些人说,如果你使用它,他们会亲自来到你的房子并杀死你。

我自己是一个新的程序员,没有受过正规的编程训练。我使用它是因为我学会了使用它。我不明白的是,如果它不是用来使用的东西,那么为什么要教我使用它?或者,从另一方面来说,它真的没有那么糟糕吗?

你对这个问题有什么看法?

370835 次浏览

总之,当您可以使用 cin.get ()这样简单的东西时,它必须暂停程序的执行,进行系统调用并分配不必要的资源。人们使用 System (“ PAUSE”)是因为他们希望程序等待,直到他们按下 Enter 键才能看到他们的输出。如果你想让一个程序等待输入,有内置的功能,也是跨平台和较少的要求。

这个文章中的进一步解释。

它之所以不受欢迎,是因为它是一种特定于平台的黑客技术,与实际学习编程毫无关系,而是为了绕过 IDE/OS 的一个特性——当程序执行完毕时,从 Visual Studio 启动的控制台窗口关闭,因此新用户无法看到他的新程序的输出。

“系统中的修补”(“暂停”)运行 Windows 命令行“暂停”命令,并等待该命令终止,然后继续执行程序-控制台窗口保持打开状态,以便您可以读取输出。

更好的办法是在结尾处放置一个断点并对其进行调试,但是这样做也存在问题。

因为它不便携。
pause命令只是一个 windows/dos 程序,所以这段代码不能在 linux/macOS 上运行。此外,system通常不被认为是调用另一个程序的好方法——通常最好使用 CreateProcessfork或类似的东西。

它很慢,依赖平台,不安全。

第一: 它的作用。调用“ system”就像在命令提示符中输入命令一样。您的应用程序要进行这样的调用,需要进行大量的设置和关闭,而且开销简直是可笑的。

如果一个名为“暂停”的程序被放置到用户的 PATH 中会怎样?只调用 system (“ stop”)只能保证执行一个名为“ stop”的程序(希望您没有将可执行文件命名为“ stop”!)

只需编写您自己的使用 _ getch 的“ Puse ()”函数。当然,_ getch 也依赖于平台(注意: 它是在“ conio.h”中定义的)-但是如果你在 Windows 上开发,它比 system()好得多,而且有同样的效果(尽管提供 cout 文本是你的责任)。

基本上: 如果只需要添加两行代码,其中一行代码包含并获得更灵活的机制,那么为什么要引入这么多潜在的问题呢?

  • 慢: 它必须跳过许多 不必要的 Windows 代码和 一个简单的单独的程序 行动
  • 不可携带的: 依赖于 暂停指令
  • 不好的风格: 打一个 system电话应该只是 必要时进行
  • 打字: system("pause")更长 而不是 getchar()

一个简单的 getchar()就足够了。

正如在其他答案中列出的那样,您可以找到许多避免这种情况的理由。这一切都归结为一个原因,使其余的讨论没有意义。System()函数本质上是不安全/不可信的,除非必要,否则不应该引入程序。

对于学生作业,这个条件从未满足,因此,如果存在对这个方法的调用,我甚至不用运行程序就可以让作业失败。(这一点从一开始就很清楚。)

这都是风格的问题。它对于调试非常有用,但是在程序的最终版本中不应该使用它。这在内存问题上真的无关紧要,因为我确信那些发明这个系统(“暂停”)的人期望它会被经常使用。从另一个角度来看,计算机的内存会因为我们在计算机上使用的其他任何东西而受到限制,而且它不会像动态内存分配那样构成直接威胁,所以我建议用它来调试代码,但别无其他。

对我来说,在毫无理由地离开之前等待是没有意义的。一个已经完成工作的程序应该结束并将它的资源交还给它的创建者。

一个人也不会在一天的工作结束后,在黑暗的角落里默默等待,等待有人给他小费。

你可以从 iostream使用 std::cin.get():

#include <iostream> // std::cout, std::cin
using namespace std;


int main() {
do {
cout << '\n' << "Press the Enter key to continue.";
} while (cin.get() != '\n');


return 0;
}

此外,system('pause')很慢,并且包含一个您可能不需要的文件: stdlib.h。它依赖于平台,并且实际上调用了一个“虚拟”操作系统。

这里有一个你不应该使用它的原因: 如果你把程序传递给另一台机器,它会激怒大多数在 Windows 上运行的反病毒程序,因为它是一个安全威胁。即使你的程序只包含一个简单的 cout << "hello world\n"; system("pause"); 它的资源量很大,而且程序可以访问 cmd 命令,这被反病毒视为一种威胁。

专业的使用系统(“ PAUSE”) ; 而创建程序的小部分是为了自己调试它。如果您使用它来获得变量的结果之前和之后的每个进程,您正在使用,以确保他们正常工作。

在测试之后,将它与解决方案的其余部分一起移动到最佳状态,您应该删除这些行。当测试一个用户定义的算法并确保按照正确的顺序做事情以得到想要的结果时,这真的很好。

在测试应用程序并确保其正常工作之后,您绝不希望在应用程序中使用它。然而,它确实允许您跟踪所有正在发生的事情。根本不要将它用于最终用户应用程序。

使用 system("pause");是不好的做法和行业; 因为

  • 完全是 没必要
    若要在从 Visual Studio 运行程序时保持程序控制台窗口在结束时处于打开状态,请使用 Ctrl + F5在不进行调试的情况下运行程序,或者在 main的最后一个右大括号 }处放置一个断点。所以,在 Visual Studio 中没有问题。当然,当您从命令行运行它时,没有任何问题。

  • 这是有问题的和恼人的
    当您从命令行运行程序时。对于交互式执行,您必须在结尾处按一个键,而没有任何目的。而对于某些任务的自动化使用来说,pause是非常不受欢迎的!

  • 不能随身携带。
    Unix-land 没有标准的 pause命令

pause命令是一个内部 cmd.exe命令,不能被重写,至少在另一个答案中错误地声明了这一点。也就是说,它不是一个安全风险,而且 AV 程序对它进行诊断的说法和重写命令的说法一样可疑(毕竟,一个调用 system的 C + + 程序可以自己完成命令解释器所能完成的所有工作,等等)。而且,虽然这种暂停的方式对于 C + + 编程的通常标准来说效率极其低下,但是对于一个新手的程序来说,这一点都不重要。

所以,在这之前的一大堆答案是不正确的,你不应该在你的 main结尾使用 system("pause") 或者其他等待命令的主要原因,是上面的第一点: 它完全没有必要,它完全没有用处,它只是非常愚蠢。

system("pause");

是错误的,因为它是 Windows API 的一部分,所以它不能在其他操作系统中工作。

你应该尝试只使用 C++标准程式库中的对象,一个更好的解决方案是这样写:

cin.get();
return 0;

但是如果您的代码中有其他 cin,它也会引起问题。因为在每个 cin之后,您将点击一个 Enter\n,它是一个空格字符。cin忽略这个字符并将其保留在缓冲区中,但是 cin.get()获得这个保留字符。因此,程序的控制到达 return 0行,控制台在让您看到结果之前关闭。
为了解决这个问题,我们编写如下代码:

cin.ignore();
cin.get();
return 0;

除了已经提供的参数(不安全性、缓慢性、不可移植性... ...)之外,还缺少另一点:

如果你正在写 生产工具的任何类型,那么你应该记住:

  • 保持应用程序窗口打开是 没有应用程序的任务!试图通过任何方式(system("pause");getchar();getch()或其他任何方式)这样做,从原则上讲都是错误的。
  • 等待用户输入的应用程序阻止它在任何类型的脚本(bash 脚本、 Windows 批处理文件、 ...)中运行,这是一个非常常见的用例——谁应该在那里提供用户输入?

如果你的老师试图在他自己的脚本中用不同的输入自动测试你的程序,这些问题就已经开始了(显然它没有... ...) !

现在,如果您只是在玩弄任何类型的测试代码,那么您无论如何都会丢弃这些代码,而不会被其他任何地方(包括您的老师)看到——谁应该在乎呢?然而,问题是,你将会习惯这样的做法,甚至在你不应该使用它们的地方也会倾向于使用它们。所以最好不要一开始就习惯..。

这不重要。

在控制台程序的末尾添加一个 system("pause")getchar()std::cin.get()或任何你喜欢的东西就是 完全是为了程序员在开发期间的利益。这样一行的 只有用途是确保在程序员可以查看之前控制台不会关闭,当从某个 IDE 内部执行程序时,这些 IDE 喜欢在执行结束时关闭控制台。

这行代码永远不会成为可执行的产品代码,因为为什么有人会在从控制台执行的程序的末尾添加“按任意键继续”呢?这不是正常的控制台程序 UI 的工作方式,他们从来没有这样做过。

一般来说,使用 system()是不好的做法,但这是另一回事。