可能重复:
不推荐使用 getch
正如标题所说,这两种方法有什么区别?我是新手,所以我对它们的用法感到困惑......
至少在我知道的实现中,函数本身没有区别。实际上,它们通常只是完全相同功能的两个不同名称。
至于有两个名字的原因:确实没有一个很好的名字。微软的某个人显然没有仔细阅读该标准的要求,并且基于对它的误解做出了一些相当……糟糕的决定。
首先,没有在标准标头中声明,因此更改名称并不是从1getch
开始的真正必要的。其次,如果他们确实需要更改名称,那么无论如何都不对 - 为实现保留的名称以下划线开头(他们做得非常正确),然后是另一个下划线或大写字母(他们弄错了) . 换句话说,如果他们要更改名称,它应该是, 或,但至少就标准而言,它和 plain 一样糟糕。_getch
__getch
_Getch
_getch
getch
就它们之间的选择而言:我只是使用getch
它并完成它。使用_getch
实际上使您的代码(略微)不那么可移植——在大多数 Unix 系统上做同样的事情,你使用 curses,它包括一个函数来做(大部分)同样的工作——它的名字是getch
. 因此,如果您曾经移植过您的代码,则需要更改包含的标头,但名称getch
是少数几个实际上会继续工作的名称之一。如果您正在执行大量交互式 I/O,那么您可能不得不重写相当多的其他代码。
1好吧,反正也不应该。回到 16 位时代,Microsoft 的链接器有一个小问题,您必须向它传递一个额外的开关 ( /noe
) 或您定义的名称之间的任何重复,而您正在链接的库中定义的名称会导致错误。所以,那时你必须通过一个额外的开关来获取链接代码,如果它使用与库中任何东西相同的名称,而不仅仅是一个标准名称。但这几乎是古老的历史。
微软 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 可能是一种选择(Unix 服务仍然存在吗?)。
MSVC 和 POSIX 函数具有相同/相似名称的细微差别的一些示例:
getch()
在 Windows 上永远不会回显字符,总是阻塞直到有输入,需要多次调用才能读取某些键,并且不能返回错误。这些行为与 POSIX 不同。ungetch()
在 Windows 上返回传入或EOF
出错的字符。在 POSIX 上,它返回OK
or ERR
。