Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ getch()和_getch()之间的差异_C++_C - Fatal编程技术网

C++ getch()和_getch()之间的差异

C++ getch()和_getch()之间的差异,c++,c,C++,C,可能重复: 正如标题所说,这两种方法之间有什么区别?我是新来的,所以我对它们的用法感到困惑…至少在我知道的实现中,函数本身没有区别。事实上,它们通常只是完全相同函数的两个不同名称 至于有两个名字的原因:真的没有一个很好的名字。微软的一些人显然没有仔细阅读标准的要求,并基于误解做出了一些相当糟糕的决定 首先,getch不是在标准头中声明的,因此从1开始不需要更改名称。其次,如果他们确实需要更改名称,\u getch无论如何都是不正确的——为实现保留的名称以下划线开头(它们非常正确),后跟另一个下

可能重复:


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

至少在我知道的实现中,函数本身没有区别。事实上,它们通常只是完全相同函数的两个不同名称

至于有两个名字的原因:真的没有一个很好的名字。微软的一些人显然没有仔细阅读标准的要求,并基于误解做出了一些相当糟糕的决定

首先,
getch
不是在标准头中声明的,因此从1开始不需要更改名称。其次,如果他们确实需要更改名称,
\u getch
无论如何都是不正确的——为实现保留的名称以下划线开头(它们非常正确),后跟另一个下划线或大写字母(它们搞错了)。换句话说,如果他们打算更改名称,那么应该是
\u getch
,或者
\u getch
,但至少就标准而言,
\u getch
和普通
getch
一样糟糕

至于在它们之间进行选择:我只要使用
getch
,就可以了。使用
\u getch
实际上会降低代码的可移植性(略微降低)——要在大多数Unixesque系统上执行相同的操作,可以使用curses,其中包含一个函数来执行(大部分)相同的任务——它的名称是
getch
。同样地,如果你移植了你的代码,你需要改变你包含的头,但是名字
getch
是少数几个可以继续工作的名字之一。如果您正在进行大量的交互式I/O,那么可能需要重写相当多的其他代码



1好吧,反正也不应该。回到16位时代,微软的链接器出现了一个小问题,你必须给它传递一个额外的开关(
/noe
),或者你定义的名称之间的任何重复,而你正在链接的库中定义的名称将导致错误。因此,如果代码与库中的任何内容使用相同的名称,而不仅仅是标准名称,那么您必须传递一个额外的开关以获取链接的代码。这是一段非常古老的历史。

非常古老的Microsoft C编译器实现提供的函数使用的名称与POSIX/UNIX世界中的名称相同,并且/或者侵犯了用户的名称空间。请注意,其中一些是“侵权”,可能是在标准化发生之前(在MS-DOS时代)就已经发生的

很久以前的某个时候,微软决定将这些名称移动到一组为编译器实现保留的名称中。他们这样做是为了图书馆里的许多名字,严格来说,即使他们可能不必这么做。似乎他们对所有不是标准C/C++的库名称都这么做了。请注意,这不适用于SDK中的名称-即使SDK随编译器一起分发,该组头和库也在编译器实现域之外

为了与使用旧名称(不带下划线的名称)编写的程序兼容,Microsoft提供了一个库oldnames.lib,它实现了将旧名称(如
getch
)链接到新名称(
\u getch
)的别名。两个名称所指的代码完全相同。因此,就工作而言,您可以使用任意一个名称(尽管您可能需要将项目设置为链接到
oldnames.lib

如果您有使用旧名称的旧Windows代码,我认为最好只链接
oldnames.lib
,然后完成

对于新代码,我认为使用新名称(带下划线且不在oldnames.lib中链接)可能会稍微好一些。微软不赞成使用旧名字,其他所有的名字都是相同的,这可能会使天平倾斜。如果您最终将代码移植到POSIX系统或将POSIX代码移植到Windows,则更有可能提醒您可能需要注意的区域。这些函数的外观和行为可能与POSIX版本类似,但它们可能需要以稍微不同的方式使用,特别是在错误处理中

或者,您可以尝试使用PDCurses之类的库,或者使用您自己的包装器来提供可移植性,这取决于它对您的价值。或者,如果您真的想在Windows上实现POSIX的可移植性,Cygwin可能是一个选项(Unix服务还在吗?)

具有相同/相似名称的MSVC和POSIX函数之间细微差异的一些示例:

  • Windows上的
    getch()
    永远不会回显字符,总是在有输入之前阻塞,需要多次调用才能读取某些键,并且无法返回错误。这些行为与POSIX上的不同
  • Windows上的
    ungetch()
    在出错时返回传入的字符或
    EOF
    。在POSIX上,它返回
    OK
    ERR

您在谈论的是
getch
\u getch
的哪些实现?如果你在谈论微软的实现,你真的应该看看。当你阅读文档时,你发现哪一部分令人困惑?通过更好地阐述你的问题,你会得到更好的答案,负责文档的人可能会被启发去澄清它,这样人们就不会再困惑了。@RobKennedy Kennedy and all:我困惑的部分是我应该在哪里使用getch()和我应该在哪里使用_getch()?标识符不一定必须以两个下划线或一个下划线后跟大写字母开头-这些类型的名称由实现保留供任何使用。以下划线开头的名称保留用于全局命名空间中的名称(有时用于其他用途,具体取决于中的特定C/C++标准)