分支与循环:if和else语句?switch语句?EOF是什么?缓冲区是什么?getchar怎么用?fflush不能用?

简介: 分支与循环:if和else语句?switch语句?EOF是什么?缓冲区是什么?getchar怎么用?fflush不能用?

目录

关于if--else语句:

switch语句的补充:

什么是EOF?

缓冲区是什么?

什么是getchar函数?

fflush没效果?


关于if--else语句:

#include <stdio.h>
int main()
{
  int age = 0;
  scanf("%d", &age);
  if (age < 18)
    printf("少年\n");
  else if (age >= 18 && age < 30)
    printf("青年\n");
  else if (age >= 30 && age < 60)
    printf("中年\n");
  else
    printf("老年\n");
  return 0;
}

image.gif

这是一串正常if--else语句代码,那么和下面这串意思是否相同?

#include <stdio.h>
int main()
{
  int age = 0;
  scanf("%d", &age);
  if (age < 18)
    printf("少年\n");
  if (age >= 18 && age < 30)
    printf("青年\n");
  if (age >= 30 && age < 60)
    printf("中年\n");
  if(age>=60)
    printf("老年\n");
  return 0;
}

image.gif

      答案很显然是相同的,那么区别在于,第一串代码中有if-else搭配使用时,有else判断成功会立即跳出,提高程序运行效率,而第二串代码只会一个一个去试条件是否满足,程序运行效率大大降低,因此可以看出,不写else语句其实也是可以的,但写了会提高运行效率。


switch语句的补充:

#include <stdio.h>
int main()
{
  int day = 0;
  switch (day)
  {
     case 1:
     case 2:
       case 3:
     case 4:
     case 5:
      printf("weekday\n");
      break;
     case 6:
     case 7:
      printf("weekend\n");
    break;
  }
  return 0;
}

image.gif

       当输入1-5时,会输出weekday,而输入6,7时,输出为weekend(应加入default语句判断额外情况,此处只补充知识),由此可以看出,case后可以不加任何语句而进行后续运行的,总结为:

case是switch的入口,进去后会一直循环直到遇到出口,如break,continue等。

编程好习惯:

在最后一个case语句后加上break语句。

可以避免出现在以前的最后一个case语句后面忘了添加break语句。


什么是EOF?

在编程中常常能看到这样的语句:

while(scanf("%d",&a)!=EOF)
 {
 ......
 }
while(ch=getchar!=EOF)
 { 
 ......
 }

image.gif

诸如此类的语句,那么什么是EOF?在C语言库中,我们可以看到官方对其的定义为:

#define EOF -1

image.gif

      那么EOF即可以理解为-1 其实在C语言中,EOF的全称为end of file,是文件结束的标志,每一个文件在结束的末尾都会加上一个EOF。那么应用到scanf或getchar函数(后续会讲解)中,这涉及到它们的返回值问题,scanf在读取成功会返回数据的个数,getchar成功会返回字符的ASCII码值,而共同点是若读取失败会返回EOF。

      因此诸如上述代码语句可以理解为,一直进行输入,若输入失败则会返回EOF,不满足while的条件,循环也就停止了,语句的含义就是不断让用户进行输入,直到跳出循环(也可以输入CTRL+Z主动跳出循环)。


缓冲区是什么?

在C语言的相关书籍中,或多或少都会提及到缓冲区的问题,那么什么是缓冲区?

      缓存区:C语言中的缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。

提到这个问题,就需要看这个很经典的问题:看下面这个程序有问题吗?

#include <stdio.h>
int main()
{
  char password[20] = {0};
  printf("请输入密码:>");
  scanf("%s", password);
  printf("请确认密码(Y/N):");
  char input = 0;
  scanf("%c", &input);
  if ('Y' == input)
    printf("确认成功\n");
  else
    printf("确认失败\n");
  return 0;
}

image.gif

提示用户输入密码,输入后确认密码,如果输入Y则输出成功,否则失败。

看似没问题,那么事实上进行运行后会发现以下问题:

image.gif编辑

我们会发现,输入密码后还没输入Y就结束程序了,我们调试看一下原因:

image.gif编辑

调试会发现,password没有任何问题,而input却直接赋予了"\n",这便是缓冲区;

image.gif编辑

       运行程序输入密码时,我们会输入"123456回车",输入回车证明我们输入结束了,可以进行后续操作了;而程序在进行读取时会读取缓冲区中的数据,事先会把"123456回车"放到缓冲区中,而scanf读取的时候只读走了123456,缓冲区中还存在"\n",所以就导致后续的scanf直接把"\n"读走了;因此不会进行赋值。

      那么如何解决这个问题?很简单,在下次scanf前把缓冲区中的数据清除掉就可以了,因此就引入了getchar函数。

什么是getchar函数?

image.gif编辑

这是cplusplus对getchar函数的定义,由此可见它也是一个输入函数。


我们只需要用getchar函数把缓冲区的剩余部分都清除就可以了:

#include <stdio.h>
int main()
{
  char password[20] = {0};
  printf("请输入密码:>");
  scanf("%s", password);
  getchar();
  printf("请确认密码(Y/N):");
  char input = 0;
  scanf("%c", &input);
  if ('Y' == input)
    printf("确认成功\n");
  else
    printf("确认失败\n");
  return 0;
}

image.gif

这样程序就可以运行了,但若输入是"123456空格abc回车",会发现问题又出现了:

image.gif编辑

      这是因为,scanf只读取空格前面的内容,后面的getchar并没有达到清除缓存区的作用,于是有下面这个方法可以根源解决问题:

#include <stdio.h>
int main()
{
  char password[20] = {0};
  printf("请输入密码:>");
  scanf("%s", password);
  while (getchar () != '\n')
  {
    ;
  }
  printf("请确认密码(Y/N):");
  char input = 0;
  scanf("%c", &input);
  if ('Y' == input)
    printf("确认成功\n");
  else
    printf("确认失败\n");
  return 0;
}

image.gif

直接利用while循环读到'\n'为止,于是便可以清除缓存区。


fflush没效果?

       在C语言函数库中,自然是有清除缓存区这样的函数库的,例如fflush函数,但在新版本的vs上,这个函数被取消了,因此无法使用,还是使用循环清除缓存区比较好。

相关文章
|
Apache SQL HIVE
带你读《Apache Kylin权威指南》之二:快 速 入 门
从最早使用大数据技术来做批量处理,到现在越来越多的人要求大数据平台也能够如传统数据仓库技术一样支持交互式分析,随着数据量的不断膨胀、数据平民化的不断推进,低延迟、高并发地在Hadoop之上提供标准SQL查询能力成为必须攻破的技术难题。而Apache Kylin的诞生正是基于这个背景,并成功地完成了很多人认为不可能实现的突破。
|
XML IDE Java
Android gradle.properties 基础使用和常规配置
Gradle 是一个开源构建自动化工具,其设计足够灵活,可以构建几乎任何类型的软件。
|
存储 算法 数据库
一起聊聊图像质量和美学评估的数据集
图像质量和美学评估是计算机视觉领域中热点的研究问题,并且极具应用前景,可与众多实际应用深度结合。评价一张图片,主要从两个方向,一个是图像的质量,如像素、清晰度、有无噪声等,一个是图像的感觉,也就是美学,如构图、颜色、内容主体等。通过这两个方面就可以评价一张图片的好坏,通过计算机视觉算法,可以为图片自动评分,得分高的图片被认为较好,可以用于推荐和搜索等应用场景。本文主要聊聊一些关于图像质量和美学评估
14162 1
|
存储 关系型数据库 MySQL
MySQL MVCC全面解读:掌握并发控制的核心机制
【10月更文挑战第15天】 在数据库管理系统中,MySQL的InnoDB存储引擎采用了一种称为MVCC(Multi-Version Concurrency Control,多版本并发控制)的技术来处理事务的并发访问。MVCC不仅提高了数据库的并发性能,还保证了事务的隔离性。本文将深入探讨MySQL中的MVCC机制,为你在面试中遇到的相关问题提供全面的解答。
1015 2
|
8月前
|
人工智能 JavaScript 前端开发
LangGraph架构解析
本文深入解析了传统Agent开发的三大痛点:状态管理碎片化、流程控制复杂及扩展性差,提出使用LangGraph通过有向图模型重构工作流,将LLM调用与工具执行抽象为节点,实现动态流程跳转。文中详述LangGraph四大核心组件——状态机引擎、节点设计、条件边与工具层集成,并结合生产环境最佳实践,如可视化调试、状态持久化与人工干预机制,最终对比LangGraph与传统方案的性能差异,给出选型建议。
1636 0
|
11月前
|
人工智能 编解码 芯片
告别低效沟通|让技术提问不再头疼-这套高效AI提问模板来帮你
不会向ai提问,不知道怎么提问的 可以看看
21189 1
告别低效沟通|让技术提问不再头疼-这套高效AI提问模板来帮你
|
9月前
|
人工智能 自然语言处理 安全
AI技术发展下,单智能体局限性凸显,如何通过MCP和A2A协议实现智能体团队协作转变?
本文智能体专家三桥君探讨了AI智能体协作的关键技术MCP(工具调用协议)和A2A(智能体协作协议)。MCP扩展智能体功能边界,支持动态连接外部工具;A2A实现智能体间的安全协作与状态同步,通过AgentCard实现能力匹配。二者集成后,可构建跨框架协作生态,解决复杂任务处理难题。三桥君指出,拥抱该技术体系是突破单智能体局限、实现AGI落地的核心路径。
413 0
|
存储 人工智能 弹性计算
从“云+原神”到“云上星穹”,阿里云支持米哈游新游全球首发
近日,阿里云支持米哈游新作《崩坏:星穹铁道》正式上线,首发当天全网下载量突破2000万,当日登上iOS免费榜与畅销榜的总榜第一及其他多国榜首。
|
数据安全/隐私保护 开发者
六、ArkTS 常用组件-按钮(Button)/切换按钮(Toggle)/文本输出(TextInput)
`Button` 组件是 HarmonyOS 应用开发中的基本组件之一,主要用于响应用户的点击操作。它支持两种使用方式:不包含子组件和包含子组件。不包含子组件时,`Button` 通过 `label` 属性设置按钮上的文字,同时提供 `options` 参数来配置按钮类型和点击效果;包含子组件的方式则允许更灵活的内容展示,如图片或复杂布局,此时无需设置 `label`。此外,`Button` 组件还提供了设置背景颜色、边框圆角等样式的方法,以及绑定点击事件的功能,使开发者能够轻松实现丰富的交互体验。
995 0
六、ArkTS 常用组件-按钮(Button)/切换按钮(Toggle)/文本输出(TextInput)

热门文章

最新文章