iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >GetChar缓存机制深入剖析
  • 534
分享到

GetChar缓存机制深入剖析

GetChar缓存机制 2022-11-15 22:11:42 534人浏览 安东尼
摘要

与缓存区相关最常见的操作就是字符的输入与输出操作getchar,getc,getch,getche,gets系列函数。 第一个例子(与getchar有关):#include<s

缓存区相关最常见的操作就是字符的输入与输出操作getchar,getc,getch,getche,gets系列函数。

第一个例子(与getchar有关):


#include<stdio.h> 
int main() 

    int ch; 
    ch=getchar(); 
    ch=getchar(); 
    printf("%d\n",ch); 
    return 0; 


代码如上,当输入一个字符按下回车后程序没有等待你二次输入就结束了,而且无论输入什么运行结果均是10,是不是很奇怪(反正我第一次遇到时感觉是很奇怪),更奇怪的是当你一次性输入多个字符如abcd结果又正确的打印出了98,为什么呢?这就是缓冲区的原因。

解释如下:getchar定义在stdio.h文件中,我们在stdio.h中可以找到其相关的定义:


#define getchar()         getc(stdin)//即getchar等同于调用getc(stdin)

我们又找到getc的定义

#define getc(_stream)     (--(_stream)->_cnt >= 0 \ 
                ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream)) 

将其展开即得:

if(--(stdin)->_cnt>=0) 
      return 0xff&*(stdin)->ptr++; 


else 
        return filbuf(stdin); 

代码译如下stdin是标准输入流,查看MSDN与stdio.h中可以看到定义如下:

Stdio.h中:


#define stdin  (&_iob[0]) 

跟踪即可得:

_CRTIMP extern FILE _iob[]; 

从上面代码可得_iob是FILE结构类型的,查看stdio.h中可以看到FILE结构体定义如下:

struct _iobuf { 
        char *_ptr; 
        int   _cnt; 
        char *_base; 
        int   _flag; 
        int   _file; 
        int   _charbuf; 
        int   _bufsiz; 
        char *_tmpfname; 
        }; 


从FILE结构中我们可以得到了上面getc宏定义中使用的_cnt,_ptr成员,但这些都是次要的,我们应该不难发现有这样几个成员_bufsize,_base分别对应的是缓冲区大小,缓冲区基地址,从这里得到一个显而意见的结论就是getchar函数使用了缓冲机制。(_cnt对应的是缓冲区的输入的字节数目,_ptr对应的是读指针的位置)

getc宏定义详解


--(stdin)->_cnt>=0 

此句判断是否缓冲区内有数据,有的话就减一(表示又读了一个),并读取数据return 0xff&*(stdin)->ptr++,读完成后,将读指针向前移一个位置【重要】

好了,讲了这么多都是铺垫,现在回到正题为什么会出现上述结果:)

出现上述结果追根结底还是由于getchar函数使用了缓冲(看了上面的,我想大家也知道了,确实使用了缓冲),当输入一个字符按下回车后程序没有等待你二次输入就结束了,而且无论输入什么运行结果均是10,这是因为当用户输入了一个字符后,并按下回车后,缓冲中会存入用户输入的字符以及换行键的ASCII码(10 ~)【略去的回车的ASCII码13,可能是为了跨平台,在linux下,回车后就是换行10,windows下回车是先回车回到首行,再换行,即13 10】(执行第一次getchar实际上是执行getc的else语句,填充缓存区后_cnt=2,_prt指向0位置,执行完后_cnt=1,_prt指向1位置),第二次执行getchar时,调用getc不会再执行else语句,执行的是if语句,故第二次不再等待用户输入了,直接执行,执行后cnt=0,prt指向位置2,并返回ptr指向位置1时的结果,即10,由于10为换行键,当执行遇到此时,会在执行完后清空缓存,ptr重新指向了位置0,cnt=0。

当输入abc的时候分析一样,只不过扫行了第二个getchar后,cnt=2,ptr指向了位置2。

--结束END--

本文标题: GetChar缓存机制深入剖析

本文链接: https://www.lsjlt.com/news/172521.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • GetChar缓存机制深入剖析
    与缓存区相关最常见的操作就是字符的输入与输出操作getchar,getc,getch,getche,gets系列函数。 第一个例子(与getchar有关):复制代码 代码如下:#in...
    99+
    2022-11-15
    GetChar 缓存机制
  • 深入剖析Android消息机制原理
    在Android中,线程内部或者线程之间进行信息交互时经常会使用消息,这些基础的东西如果我们熟悉其内部的原理,将会使我们容易、更好地架构系统,避免一些低级的错误。在学习Andr...
    99+
    2022-06-06
    Android
  • Assert(断言实现机制深入剖析)
    断言(assert)的作用是用来判断程序运行的正确性,确保程序运行的行为与我们理解的一致。其调用形式为assert(logic expression),如果逻辑表达式为假,则调用ab...
    99+
    2022-11-15
    Assert 断言
  • 深入剖析MongoDB的事务处理与并发控制机制
    深入剖析MongoDB的事务处理与并发控制机制摘要:MongoDB是一种流行的NoSQL数据库,它以其高性能和可扩展性而闻名。然而,MongoDB最初并不支持事务处理和并发控制,这在某些情况下可能引发数据一致性和完整性的问题。为了解决这些问...
    99+
    2023-11-04
    MongoDB 事务处理 并发控制
  • 深入剖析MongoDB的数据复制与故障恢复机制
    深入剖析MongoDB的数据复制与故障恢复机制引言:随着大数据时代的到来,数据的存储和管理变得愈发重要。在数据库领域,MongoDB作为一种广泛应用的NoSQL数据库,其数据复制和故障恢复机制对于保障数据的可靠性和高可用性至关重要。本文将深...
    99+
    2023-11-04
    MongoDB 故障恢复 数据复制
  • 带你深入理解MyBatis缓存机制
    目录一、简介1、缓存机制介绍2. 一级缓存和二级缓存二、一级缓存三、二级缓存3.1 mybatis自带的二级缓存3.1.1 代码测试二级缓存3.1.2 查询结果存入二级缓存的时机3....
    99+
    2022-11-12
  • 深层剖析java应用开发中MyBayis缓存
    目录什么是 MyBatis 缓存MyBatis 缓存分类1、⼀级缓存:SqlSession 级别,默认开启,并且不能关闭。(默认开启)2、二级缓存:Mapper 级别,...
    99+
    2022-11-12
  • 深入理解MySQL中MVCC与BufferPool缓存机制
    目录一、MVCC机制undo日志版本链与read-view机制版本链比对规则二、BufferPool机制三、总结一、MVCC机制 MVCC(Multi Version Concurr...
    99+
    2022-11-13
  • java内存管理机制剖析(一)
    最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下。1.1 java内存区域 当java程序运行时,java虚拟机会将内存划分为若干个不同的数据区域,这些内存区域创建和销毁的时间各不相同,所承担的功能也不相同,他们各...
    99+
    2023-06-02
  • 深入剖析Golang Facade模式的内部机制与运行原理
    Golang中的Facade模式是一种结构型设计模式,用于隐藏系统复杂性并提供一个简单的接口供客户端使用。它通过为客户端提供一个统一...
    99+
    2023-10-08
    Golang
  • 深度剖析java中JDK动态代理机制
    摘要相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象。代理模式使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用...
    99+
    2023-05-31
    jdk 动态代理 ava
  • 深入剖析Go语言垃圾回收机制的原理与应用
    Go语言的垃圾回收机制是一种自动的内存管理机制,它通过解决内存分配和回收的问题,使得开发者无需显式地管理内存,可以更专注于业务逻辑的...
    99+
    2023-10-08
    Golang
  • 深入浅析java中的Integer缓存
    这篇文章给大家介绍深入浅析java中的Integer缓存,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Integer类实质上也是一个普通的java类,即使值相同,也是不同的对象。 例如 Integer a =...
    99+
    2023-05-31
    java 缓存 integer
  • 深入浅析Java中的内存分配机制
    本篇文章给大家分享的是有关深入浅析Java中的内存分配机制,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java 内存分配深入理解Java程序运行在JVM(Java ...
    99+
    2023-05-31
    java 内存分配 ava
  • Flutter图片加载与缓存机制的深入探究
    目录前言图片控件 图片解析 缓存管理 ​新增缓存 缓存清理 图片加载 滑动中处理 总结 前言 今天来学习一下 Flutter 自身是如何加载图片和管理图片的。 Flutt...
    99+
    2022-11-12
  • 深入浅析MyBatis中的一级缓存与二级缓存
    本篇文章给大家分享的是有关深入浅析MyBatis中的一级缓存与二级缓存,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。MyBatis缓存我们知道,频繁的数据库操作是非常耗费性能的...
    99+
    2023-05-31
    mybatis 二级缓存 一级缓存
  • 深入浅析Android消息机制
    在Android中,线程内部或者线程之间进行信息交互时经常会使用消息,这些基础的东西如果我们熟悉其内部的原理,将会使我们容易、更好地架构系统,避免一些低级的错误。 每一个And...
    99+
    2022-06-06
    Android
  • Go 包管理机制深入分析
    前言随着 Go 语言的深入使用,其依赖管理机制也一直是各位 Gopher 热衷于探讨的话题。Go 语言的源码依赖可通过 go get 命令来获取,但自动化程度不高,于是官方提供了 Dep 这样的自动化批量管理依赖的工具。...
    99+
    2023-06-04
  • 深入剖析Go语言中的垃圾回收与内存管理
    在Go语言中,垃圾回收(Garbage Collection,简称GC)是自动进行的,开发者不需要手动管理内存。Go语言的GC使用的...
    99+
    2023-10-12
    Go语言
  • 如何解析Eureka 缓存机制
    今天就跟大家聊聊有关如何解析Eureka 缓存机制,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。引言Eureka是Netflix开源的、用于实现服务注册和发现的服务。Spring C...
    99+
    2023-06-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作