getch()、_sleep() 函数的正确用法

2023-10-26

前段时间由于需要,写了一段代码,用到了函数 getch(),但是当时出错了,提示该标识符未被定义,一时无解。后来又有一个朋友,问我怎么将一个字符串中的字符以一种动态的方式进行输出,我当时告诉他的是使用 sleep() 函数,也没有细想,后来发现,根本不存在 sleep() 这个函数。这个糗可是出大发了!

在很多的官方的与非官方的教程中,getch() 都是定义在头文件 stdlib.h 中的,甚至还有的说,是在 stdio.h 中。比如下面的例子:

#include <stdio.h>
void main()
{
    puts("Hello World!");
    getch();
}

看着好像很高深莫测的样子,但是一看,嘿!getch() 函数可没有在 stdio.h 里面定义呢!
先不说别的,尝试编译,提示“test.cpp(5) : error C2065: ‘getch’ : undeclared identifier”,看来果真不是在 stdio.h 里。

那么 getch() 到底定义在哪里呢?

通过阅读 c++ 的头文件,可以发现,在 conio.h 中定义了如下内容:
CONIO.H

_CRTIMP int __cdecl _getch(void);

那我们现在再来试试,包含了 conio.h 文件后,又是一个怎么样的结果:

#include <stdio.h>
#include <conio.h>
void main()
{
    puts("Hello World!");
    getch();
}

尝试编译,成功通过。在 cmd 里执行也通过。

看来,的确是尽信书不如无书。连教程都能出错。现在我们干掉了一个 getch(),可还剩下一个 sleep() 呢?前文说了,这个函数,在头文件里根本就不存在。那我们无论如何也是找不到这个函数的。不过,找不到它,我们还可以试着去找和它长的很像的其他的函数。

事实证明,在不借助网络,不借助 msdn 和其他任何操作手册的情况下,找一个函数最好的方法就是在头文件所在的文件夹中用 find。
C:\Program Files\Microsoft Visual Studio\VC98\Include> find *.h “sleep” /i
共搜索到如下结果:

//---------- MAPIWIN.H
void WINAPI     Sleep(DWORD dwMilliseconds);
//---------- STDLIB.H
_CRTIMP void __cdecl _sleep(unsigned long);
//---------- WINBASE.H
WINBASEAPI VOID WINAPI Sleep(DWORD dwMilliseconds);

可见,MapiWin.h 和 WinBase.h 中关于 Sleep() 函数的定义实际上是一样的。
测试过程我就略过了,当然我肯定是测试过,不过就不在这儿写了,现在,贴上应用 stdlib.h 中的 _sleep() 的代码。

//Using _sleep() declared in stdlib.h
#include <stdlib.h>
#include <stdio.h>
void main()
{
    int i=6;
    for(;--i;_sleep(1000)) 
        printf("%d\r", i);
    printf("Boom!\n");
}

stdlib.h 中的 _sleep() 一帆风顺,可是 WinBase.h 中的 Sleep() 却有些不靠谱。经测试,在只包含 WinBase.h 的情况下无法编译成功。原因是一些自定义类型没有定义,例如 DWORD 和 HANDLE 一类。因为我查看了 WinBase.h 的内容,并没有定义这些类型,也没有包含含有这些类型的文件。那么现在该怎么办呢?

还记得有一个头文件 windows.h 吗?在该文件第 164 行(不同版本的可能有差别),有一处#include “winbase.h”,而且显然,windows.h 里面定义了各种的数据类型(#include “windef.h”),那么包含 windows.h,是否能够调用 Sleep() 了呢?经测试,答案是肯定的。这里就不详述测试的过程了,直接贴代码

//Using Sleep() declared in WinBase.h
//Including windows.h instead for more supportings.

#include <windows.h>
//#include <WinBase.h>
#include <stdio.h>

void main()
{
    int i=6;
    for(;--i;Sleep(1000)) printf("%d\r", i);
    printf("Boom!\n");
}

看来,有些时候,不是定义了函数,就可以使用的。

不过,在这里我还要多说一点是,虽然在实际的代码中,我们 #include 的是 windows.h 文件,但我们不能说 Sleep() 就是 windows.h 中定义的。毕竟,它只是在 windows.h 中又包含了 WinBase.h。

好了,来一个文末总结——

  1. getch() 函数定义在头文件 conio.h 中,函数声明为
    _CRTIMP int __cdecl _getch(void);

  2. _sleep() 函数定义在头文件 stdlib.h 中,函数声明为
    _CRTIMP void __cdecl _sleep(unsigned long);

  3. Sleep() 函数定义在头文件 WinBase.h 中,不过使用的时候应包含的是 windows.h 头文件而非 WinBase.h,函数声明为
    WINBASEAPI VOID WINAPI Sleep(DWORD dwMilliseconds);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

getch()、_sleep() 函数的正确用法 的相关文章

  • C++ 析构函数和函数调用顺序

    假设我有以下代码片段 Foo foo return bar 现在 C 标准是否保证 bar 将在 foo Foo 之前调用 或者这是编译器 实现的选择 Thanks 这是有保证的行为 实际执行过程如下 0 enter block scope
  • C++ 令人头疼的命名空间

    好吧 这个问题已经发生了一些变化 我想尝试从我正在追求的基本目标开始 重新 创建在 C 资源获取和初始化中包装遗留 C 语言实体的库代码 并提供基本或更好的异常保证 使此代码的客户端能够以非常自然的 C 方式使用它 而不会为现有代码创建大量
  • LINQ TO ENTITY 无法与枚举类型进行比较

    下面是枚举叶子 public enum Leaves Annual 0 Medical 1 Hospitalization 2 Unpaid 3 下面是linq查询 public ActionResult ApproveLeave int
  • 为多线程 UDP 客户端执行“close ()”时套接字描述符未释放

    我在下面编写了 UDP 客户端 它基本上生成一个单独的线程来接收数据报 但是数据报仅在主线程中发送 现在 在 Linux 发行版上实例化 udpClient 1 UDP 客户端后按 ctrl D 实现退出循环 围绕 getline 调用 并
  • DataGridView 自动完成组合框列不保留初始单元格离开时的值

    我有一个带有自动完成组合框列的绑定 dataGridView 并且自动完成功能正在工作 只是我观察到一种有点令人恼火的行为 当我第一次在自动完成单元格中键入文本并使用 tabKey 移动到下一个单元格时 我的选择不会保留 我选择的内容将被清
  • C# 按下按钮时跳出循环

    我有一个简单的 C foreach 循环 如何在按下按钮时跳出循环 它不在backgroundWorker线程中 所以我不能使用backgroundWorker Cancellation Pending 在表单中创建一个布尔标志 将事件处理
  • 正确别名向量

    我无法在其他地方找到答案 所以我想我只需要问这个 我正在尝试获取向量 其中存储 int 指针 的别名 如下所示 void conversion Engine ENGINES The Engine class has a vector of
  • 如何将 list 对象附加到另一个对象

    在 C 中 我有两个list
  • 以 ASCII 字符串形式获取 MemoryStream 内容的快速方法

    我在 MemoryStream 中有一个 JSON 字符串 我使用以下代码将其作为 ASCII 字符串获取 MemoryStream memstream new MemoryStream Write a JSON string to mem
  • 如何设置属性选择器的值 Expression>

    我需要使用模式工厂的想法将 Person 类实体中的实体属性 Address 与 FactoryEntities 类中的表达式 linq 相关联 看看这就是我所拥有的并且我想要做的 Address address new Address a
  • 在 C++ 中重用异常处理代码

    我有这两个函数 具有重复的异常处理 其唯一目的是显示错误消息 void func1 noexcept try do task do another task catch const std out of range e show msg O
  • 使用 .NET Core Razor Pages 将文件下载到浏览器

    使用 ASP NET Razor Pages 我尝试将文件下载到浏览器 在页面 html 中 使用这样的链接效果很好 href DownloadableFiles testB csv download newname gt Download
  • 如何获取 TFS 2013 中所有用户的列表

    我正在使用 Team Foundation Server TFS 2013 和 Visual studio 2012 我需要 TFS 中所有用户的列表 有没有办法使用C 获取TFS中的所有用户 从TFS 2010获取用户列表 您可以尝试使用
  • 实体框架..自引用表..获取深度=x的记录?

    我成功地在实体框架中使用自引用表 但我不知道如何获得所需深度的记录 这应该是什么逻辑 Model public class FamilyLabel public FamilyLabel this Children new Collectio
  • 如何使用 GCC 在 C 上编译库?

    我用这些文件创建了一个库pila h and pila c 我编译文件pila c with gcc pila c c这个库运行良好 我已经测试过了 然后我又做了一个图书馆 这个库有文件pila funciones extra h and
  • 宏中 do { } while(0) 与 ({ }) 的优点?

    Stack Overflow 上有很多关于使用的问题do while 0 在宏中 但这有点不同 我明白为什么do while 0 用于将多行代码包装在宏扩展中 但我经常看到另一种形式 The form 的优点是它是一个表达式并且可以有 返回
  • 如何在c#中打印全尺寸图像

    我正在尝试用 C 打印图像 它是由 Adob e Acrobat 从 PDF 创建的完整 8 5x11 尺寸的 tiff 当我使用下面的代码用 C 打印它时 它垂直打印正确 但水平打印不正确 水平方向被推了大约半英寸 我将图像的原点设置为
  • GridView,在代码中添加标题行第 2 部分

    这是这篇文章的延续 但添加了完整的代码 ASP NET GridView 在代码中添加标题行 https stackoverflow com questions 19119004 asp net gridview adding header
  • C# - 平移光标

    我正在 PictureBox 控件中实现大图像的平移 并且设置适当的方向平移光标没有问题 但是 我似乎找不到用于平底锅原点的图像 内部带有箭头的圆圈 我在哪里可以找到它 我觉得image您正在寻找的内容未包含在框架中 每个应用程序都使用自己
  • XslCompiledTransform 和自定义 XmlUrlResolver:“具有相同键的条目已存在”

    有没有办法调试由自定义 XmlUrlResolver 从数据库加载的 XSLT 文档 或者有人知道下面的错误消息是关于什么的吗 我有一个导入通用 xslt 文档的 XSLT 样式表

随机推荐

  • Java课题笔记~Element UI

    Element 是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库 用于快速构建网页 Element 提供了很多组件 组成网页的部件 供我们使用 例如 超链接 按钮 图片 表格等等 如下图左边的是我们编写页面看到的按钮 上图右边的
  • Redis3.0 集群搭建

    redis3 0 部仅提供了哨兵监控 热切换 还提供了集群解决方案 接下来简单的搭建redis3 0集群 1 新建三个redis server实例 我们可以将redis conf分别copy到7001 7002 7003的文件夹中 并修改相
  • easyui-datagrid获取行和列数据

    1 获取当前行 var row dg datagrid getSelected 2 获取所有选中行 var rows dg datagrid getSelections 3 获取所有行 var rows dg datagrid getRow
  • 安卓11上的存储权限问题

    这篇文章 想来发布的有些晚了 安卓11已经发布多时了 关于安卓11上的存储权限变更的文章数不胜数 所以这篇文章只做为自己的一个简单的记录吧 在说11之前 我们先回忆以下10上存储权限的变更 每个应用会生成自己对应的沙盒文件路径 自己的应用只
  • 计算机基础相关知识面试题

    之前写过一篇面试题 但是在春招面试 笔试问了很多计算机网络 数据结构 操作系统等相关知识点记点之前总结的还是不够参考的 再来一篇 顺序有点乱 但是每一个都是参考的 已备大家复习使用吧 文章目录 UDP 传输控制协议 和TCP 用户数据报协议
  • Redis——初识Redis

    Redis简介 Redis的数据结构致力于帮助用户解决问题 而不是像关系型数据库那样 要求用户扭曲问题来适应数据库 除此之外 通过复制 持久化和客户端分片 client side sharding 等特性 用户可以很方便的将Redis扩展成
  • 基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二十八)Gamma校正

    Vries的教程是我看过的最好的可编程管线OpenGL教程 没有之一 其原地址如下 https learnopengl cn github io 05 20Advanced 20Lighting 01 20Advanced 20Lighti
  • 编写一个golang websocket示例

    示例代码 创建一个websocket对象 var ws websocket Dial ws localhost 8000 echo http localhost 发送消息 if err ws Send byte hello world er
  • Latex编译中文出现的问题

    Latex编译中文出现的问题 记录一下使用latex编译中文遇到的一些问题 本文是在win11系统下使用的TexStudio MikTex组合 编译使用的是pdfLatex 编辑器的设置 首先会发现 编辑器中的中文字符全是乱码 这时 在Te
  • 应用于标签的伪类选择器(link、visited、active、hover)

    CSS3根据选择符的用途可以把选择器分为标签选择器 类选择器 ID选择器 全局选择器 组合选择器 继承选择器和伪类选择器等 伪类选择符定义的样式最常应用于 a 标签上 它表示4种不同的状态 link 未访问链接 visited 已访问链接
  • GnuWin32的安装与使用

    使用过Linux的伙计估计都会喜欢上linux各种各样强大的命令如 find vim cp mv wget curl grep ls等等 而GnuWin32使windows用户可以在命令行窗口中使用各种各样的linux命令 就跟使用普通的w
  • lighttpd不支持Expect: 100-continue的解决办法

    由于lighttpd1 4 21之前的版本不支持Expect 100 continue 所以有可能访问出现 HTTP 1 1 417 Expectation Failed 等错误提示 搜集整理了很多解决方法 如下 1 升级到 lighttp
  • Chrome:将禁用修改document.domain以放宽同源策略

    你好 我是tiantian 几天前 Chrome developer 博客发布了这么一篇文章 大致意思是 Chrome未来将禁用修改document domain 如果你的网站依赖于设置document domain 来解决跨域的问题 那么
  • ubuntu安装elasticsearch和head插件(所有可能出现的问题解决)超详细

    一 单例安装 首先去官网 elastic co 下载tar gz的压缩包 或者使用命令行下载 wget https artifacts elastic co downloads elasticsearch elasticsearch 6 7
  • 当鼠标光标放在一张图片上,如何显示另一张图片?

    我们会遇到一种情境 这种情境是当正常打开一个页面 有文字配有图片 可是当鼠标的光标移动到这张图片上时 会显示另一张图片 这种效果应该怎么做 在学习html和css阶段的程序员 我们可以使用hover来对图片进行处理 hover的基本意思为选
  • 【c语言】两个栈实现一个队列

    两个栈实现一个队列 核心思想 模拟出队列先进先出的数据结构 假设有两个栈input和output input模拟栈的数据插入 当需要模拟出队列操作时 input栈中的A B C D会按照D C B A的顺序进入栈output 只要outpu
  • TensorRT部署(图像分类)之engine生成及反序列化推理(第二讲)

    1 日志文件类创建 class TRTLogger public nvinfer1 ILogger public virtual void log Severity severity nvinfer1 AsciiChar const msg
  • adams怎么打开自带模型_少了这套Enscape专属模型库,你装的Enscapen废了一半

    文末领取此套Enscape离线资源库 真实植物 Enscape 我们一直都在用 大家也都很熟悉 而且Enscape作为渲染界的劳模 几乎可以保持月更的节奏 其操作简单 容易上手 渲染真实越来越多的被使用 虽然Enscape很好用 比Lumi
  • SAP MM学习笔记17-在库品目评价中的标准原价 S 和移动平均价格 V

    SAP中有2种价格 标准原价 S 和 移动平均价格 V 1 标准原价 S 2 移动平均价格 V 在MM03 会计1 Tab中 现行评价区域中 有原价管理区分 比如下面这个物料 100 100 它的原价管理区分是 S 它的合计额 就是 标准原
  • getch()、_sleep() 函数的正确用法

    前段时间由于需要 写了一段代码 用到了函数 getch 但是当时出错了 提示该标识符未被定义 一时无解 后来又有一个朋友 问我怎么将一个字符串中的字符以一种动态的方式进行输出 我当时告诉他的是使用 sleep 函数 也没有细想 后来发现 根