getch()和_getch()之间的区别

3
可能重复:

可能重复:
getch已弃用

正如标题所说,这两种方法之间有什么区别?我是新手,所以对它们的使用感到困惑...


你在谈论哪些 getch_getch 的实现?如果你在谈论微软的实现,你真的应该看一下 这个链接 - ArjunShankar
请看 https://dev59.com/K3I-5IYBdhLWcg3w-9sJ#1587158 - Michael Burr
1
当你阅读文档时,你觉得哪一部分令人困惑?通过更好地表达你的问题,你将得到更好的答案,文档负责人也可能会受到启发,澄清文档以使人们不再感到困惑。 - Rob Kennedy
@RobKennedy Kenedy和大家:我困惑的部分是在哪里应该使用getch(),在哪里应该使用_getch()? - ducnh
2个回答

4
至少在我所知道的实现中,这两个函数本身没有区别。事实上,它们通常只是完全相同函数的两个不同名称。关于有两个名称的原因:实际上并没有一个非常好的原因。微软公司的某人显然没有仔细阅读标准的要求,并基于误解做出了一些相当糟糕的决定。首先,`getch`没有在标准头文件中声明,因此改变名称实际上并不是必要的。其次,如果他们确实需要更改名称,那么`_getch`也不正确——名称保留给实现以下划线开头(他们已经做到了这一点),后跟另一个下划线或大写字母(这一点他们搞错了)。换句话说,如果他们要更改名称,应该是`__getch`或`_Getch`,但至少就标准而言,`_getch`和纯`getch`一样糟糕。关于选择使用哪个:我会使用`getch`并完成它。使用`_getch`实际上会使您的代码(稍微)不太可移植——在大多数类Unix系统上,您要使用curses,其中包括执行(大部分)相同工作的函数——它的名称为`getch`。因此,如果您要移植您的代码,您将需要更改所包含的头文件,但名称`getch`是为实际工作的少数几个名称之一。如果您正在执行大量交互式I/O,则可能需要重写相当多的其他代码。

标识符不一定要以两个下划线或下划线后跟大写字母开头 - 这些名称类型被实现保留供任何使用。 以下划线开头的名称保留用于全局命名空间中的名称(根据特定的C / C ++标准,有时还用于其他用途)。 - Michael Burr

4
非常古老的 Microsoft C 编译器实现提供了与 POSIX/UNIX 环境中相同的名称或侵犯用户命名空间的函数。请注意,其中一些“侵权”可能是在标准化之前完成的(在 MS-DOS 时代)。 很久以前,Microsoft 决定将这些名称移动到一个保留给编译器实现的名称集中。即使严格来说他们可能不必这样做,他们也为库中的许多名称执行了此操作。似乎他们几乎为所有非标准 C/C++ 库名称执行了此操作。请注意,这不适用于 SDK 中的名称 - 即使 SDK 与编译器一起分发,该组头文件和库也位于编译器实现领域之外。
为了与使用旧名称(没有下划线的名称)编写的程序兼容,Microsoft 提供了一个库 oldnames.lib,它实现了别名,将旧名称(例如 getch)链接到新名称(_getch)。两个名称都指向完全相同的代码。因此,在使事情正常工作方面,您可以使用任何名称(尽管您可能需要设置项目以链接 oldnames.lib)。
如果您有使用旧名称的旧 Windows 代码,则我认为最好只需链接 oldnames.lib 并完成。
对于新代码,我认为使用新名称(带下划线并且没有链接 oldnames.lib)可能会稍微好一些。 Microsoft 已弃用旧名称,其他条件相等,这应该是更好的选择。如果最终将代码移植到 POSIX 系统或将 POSIX 代码移植到 Windows,则有更好的机会提醒需要注意的区域。这些函数可能看起来并且大多数都像 POSIX 版本,但是可能需要以略微不同的方式使用 - 尤其是在错误处理方面。
或者您可以尝试使用类似 PDCurses 的库或使用自己的包装器提供可移植性,具体取决于它对您的价值。或者,如果您真的想在 Windows 上实现 POSIX 可移植性,则 Cygwin 可能是一个选项(是否仍然存在 Services for Unix?)。
以下是 MSVC 和 POSIX 函数之间存在微妙差异的一些示例,它们具有相同/相似的名称:
- 在 Windows 上,getch() 永远不会回显字符,总是阻塞直到有输入,需要多次调用才能读取某些键,并且无法返回错误。 这些行为与 POSIX 不同。 - 在 Windows 上,ungetch() 返回传递的字符或错误时返回 EOF。 在 POSIX 上,它返回 OK 或 ERR。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接