[C初阶]循环和分支语句

news/2023/12/1 12:19:35

目录

if...else语句

​编辑

 易犯错误

打印100以内的奇数 

switch...case语句

输出星期

 循环语句

对比判断 

1.break终止循环

2.continue

读取字符

缓冲区读取

只输出数字字符 

 for循环

do...while循环

n的阶乘求和

 循环实现动态打印

猜数字游戏【总结】

 goto

​编辑 关机程序

 goto

while循环


if...else语句

我们先引入一个重要的概念:0为真,非0为假。

分支判断语句if...else,默认情况下都只控制一条语句,如果我们想执行多条语句可以添加大括号。{}内表示代码段。

if语句默认与最近的else相匹配。

那我们如何按照自己意愿决定if...else的匹配关系呢?答案是加上大括号:

//形式1
if (condition){return x;}return y;
//形式2
if (condition){return x;}
elsereturn y;

一般推荐第二种形式代替第一种,以提高可读性。

 易犯错误
int num = 1;
if (num = 5)
{printf("hehe\n");
}

这段代码会陷入死循环,注意区分赋值和等于

//正确
if (num == 5)
//容易检查错误
if(5 == num)

打印100以内的奇数 

我们可以使用判断语句来输出100以内的所有奇数

	int i = 1;while (i <= 100){if(i%2 == 1)printf("%d\n", i);i++;}

但我们可以凭借尝试不用判断直接利用循环语句跳过2个数也能实现这个功能:

while (i <= 100){printf("%d\n", i);i+=2;}

switch...case语句

switch...case语句作为分支语句,意为开关。有的时候它比if...else语句更方便,可读性更高。

输出星期

正常模式:

int day = 0;
scanf("%d", &day);
if (1 == day)printf("星期1\n");else if (2 == day)printf("星期2\n");else if (3 == day)printf("星期3\n");else if (4 == day)printf("星期4\n");else if (5 == day)printf("星期5\n");else if (6 == day)printf("星期6\n");else if (7 == day)printf("星期天\n");

switch改写: 

当我们输入4的时候程序进入了第4个语句,成功输出了星期4但是输出了后面的分支, 你可以把它想象成电流水流,需要一个闸门控制关闭——break意为中断,类似与闸门的关闭键,遇到它就会停止。

int day = 0;scanf("%d", &day);int n = 1;switch (day)//整型表达式{case 1:  //case 后必须是整型常量表达式printf("星期1\n");break;case 2:printf("星期2\n");break;case 3:printf("星期3\n");break;case 4:printf("星期4\n");break;case 5:printf("星期5\n");break;case 6:printf("星期6\n");break;case 7:printf("星期天\n");break;}

现在我们打印休息日和工作日,可以这样修改代码:

switch (day)//整型表达式{case 1:  //case 后必须是整型常量表达式case 2:case 3:case 4:case 5:printf("工作日\n");break;case 6:case 7:printf("休息日\n");break;default:printf("输入错误\n");break;}

这里就体现了switch语句的自由性,当我们输出1-7以外的数字时,我们可以使用default关键字(默认)来处理。default不一定要写在语句最后,可以为任意位置,所以我们最好在后面加上break。

 循环语句

顾名思义,循环就是满足判断条件后就会继续重复执行的操作。

对比判断 

  

当满足条件的时候他就会一直循环,我们输入一个横真条件就会进入死循环,为了灵活的控制循环,我们还添加了break和continue对循环进行控制。

1.break终止循环

遇到break循环跳出当前循环

2.continue

遇到continue忽略循环体内后面的内容,重新开始循环(跳过本次循环)

该循环到5的时候程序会进入死循环,正确做法是将i++放到循环第一句中使其不打印5。

读取字符

如果我们想从键盘中读取多个字符的话该怎么操作呢?

读取成功时返回它的整型值(对应ascii码值),这是为了适应当它读取失败时返回EOF(-1),我们也可以手动结束读取——键盘输入ctrl+z

putchar是输出字符, 成功将返回字符并输出在屏幕上,失败返回EOF。

ch通过接收getchar的返回值,对每个字符进行判断。当我们键入回车时,getchar也会读取并判断,然后通过屏幕打印出来,所以会出现单个字符占一行的效果。

缓冲区读取

 我们实现一个简单的密码确认程序来验证一下缓存区是否存在。

当我们输入密码后敲出的回车直接被ch读取,导致直接打印确认失败,这是因为scanf在遇到\n或空格后会停止输入,剩下的内容被留在了缓冲区。为了避免这种情况,我们可以用getchar将空格给读走。

添加getchar后我们的代码能成功运行

 还有一种情况需要考虑

 为什么会发生这样的事呢?

换句话说还是没有处理干净,这时候我们利用循环来清除缓冲区的内容

只输出数字字符 

int ch = 0;
while ((ch = getchar()) != EOF)//多组输入,注意优先级加括号
{if (ch < '0' || ch > '9')continue;
/*if(ch <= '9' && ch >= '0')*/putchar(ch);
}

需要注意的是,虽然用char类型也能接收getchar的返回值,但最好还是用int(可能截断)

 for循环

for循环是对while循环的一个整合,使得我们能精确地调整循环。

for(代码1;代码2;代码3)

分别代表初始条件,判断和更新

这段代码打印了除5之外的1到10的所有数字,与while循环不同的是,当更新条件放在continue后将不会执行,而for循环中使用continue能继续执行更新条件。 

for的初始化,判断,调整三个部分可以省略, 但是省略掉判断部分,就意味着判断恒为真

 如果我们省略初始部分,可能会出现这样的结果:

 不省略前打印100次,省略后由于打印10次后j的值没有被重新初始化,导致它仍然为10。

所以最好不要随便省略判断条件

do...while循环

它的特点是:至少执行一次,一般不常用。

 下面代码的结果是?

int i = 1;
do
{if (i == 5)continue;printf("%d ", i);i++;
} 
while (i <= 10);

答案是输出1 2 3 4,同样地,由于更新条件放在continue后,执行continue后进入while循环(死循环)。

n的阶乘求和

具体思路是从1到n依次求阶乘,并依次求和。

    int i = 1;int sum = 0;int ret = 1;int n = 0;for (n = 1; n <= 3; n++){ret = 1;for (i = 1; i <= n; i++){ret = i * ret;}sum = sum + ret;}printf("%d", sum);

注意每次循环后需要将ret变为1

第二种方法(消耗低)

n!= (n-1)! * n

    int i = 1;int sum = 0;int ret = 1;int n = 0;for (n = 1; n <= 3; n++){ret = n * ret;sum = sum + ret;}printf("%d", sum);

 循环实现动态打印

给定一段字符串和同等长度的#号,使其每循环一次,左右两边进行覆盖直到#被覆盖成字符串。

#include<stdio.h>
#include<windows.h>
#include<string.h>
int main(){
char arr1[] = "welcome to here!!!!";
char arr2[] = "###################";
int left = 0;
int right = strlen(arr1)-1;
while (left <= right)
{arr2[left] = arr1[left];arr2[right] = arr1[right];printf("%s\n", arr2);Sleep(100);//休眠命令system("cls");//清空屏幕命令left++;right--;
}
printf("%s\n", arr2);
}

大家可以复制这段代码到编译器中运行,可以观察到一个简单的动态效果。

猜数字游戏【总结】

我们结合本篇学的知识,用猜数字游戏做一个复习。 

编写一个建议菜单:

void menu()
{printf("*********************************\n");printf("**********  1. play  ************\n");printf("**********  0. exit  ************\n");printf("*********************************\n");
}
int main()
{int n = 0;do{menu();scanf("%d", &n);switch (n){case 1://game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择!\n");break;}}
while (n);return 0;
}

 接下来我们完善game函数 

要想实现猜数字这个功能,我们得需要电脑生成随机数,而rand是专门用来生成随机数的函数。

但rand生成的数字是伪随机,第二次运行程序的数字和第一次一模一样

所以我们用srand(随机数初始化设置器)来让随机数变成真随机。

一直在变的是时间,所以用时间函数来设置初始化。它的返回值是一个时间戳(整形)我们这里是产生随机值,所以可以传NULL来产生随机值。

 注意srand只能设置一次,所以不参与循环,我们可以把它添加到do...while循环里

	srand((unsigned int)time(NULL));

 由于time函数返回类型是time_t,而srand的参数是无符号整形,所以我们得强制转换。

void game()
{int num = rand()%100+1;//1-100之间int guess = 0;while (1){printf("请猜数字:>");scanf("%d", &guess);if (guess < num)printf("猜小了\n");else if (guess > num)printf("猜大了\n");else{printf("猜对\n");break;}}
}

把上面的代码整合一下,我们的猜数字游戏就可以运行起来了,赶快去体验一下自己的第一个c语言小游戏吧!

 goto

作为一个跳出一层或多层循环的函数,goto语句能实现的功能都能被其他语句实现,而且它的使用可能会导致程序出现一些问题(例如跳过某些程序可能导致程序出现不可调试的bug等)。它的出场率并不高,一般出现在需要一次性跳出多个循环的场景。(break只能跳出一层循环)

 关机程序

顾名思义,就是能让电脑在特定时间关机的程序。我会用两种方式来写这个程序

 goto

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{system("shutdown -s -t 60");//60秒内关机
again:printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");char input[20] = { 0 };scanf("%s", input);if (strcmp(input, "我是猪") == 0){system("shutdown -a");printf("关机取消\n");}elsegoto again;return 0;
}

运行结果:

while循环

int main()
{char input[20] = { 0 };system("shutdown -s -t 60");while (1){printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");scanf("%s", input);if (strcmp(input, "我是猪") == 0){system("shutdown -a");printf("关机取消\n");break;}}return 0;
}


http://www.ppmy.cn/news/971695.html

相关文章

线性结构:双端队列

文章目录 双端队列定义双端队列应用回文词判定 双端队列定义 双端队列Deque是一种有次序的数据集 跟队列相似&#xff0c;其两端可以称作“首”“尾”端&#xff0c;但deque中数据项既可以从队首加入,也可以从队尾加入;数据项也可以从两端移除。某种意义上说,双端队列集成了栈和…

上传了ipa但iTunes Connect没有构建版本问题

转载&#xff1a;上传了ipa但iTunes Connect没有构建版本问题 目录 一、首先登录iTunes Connect 后台 查看ipa构建情况 二、错误反馈邮件示例及说明 证书类型不正确 Invalid App Store Icon 三、修改相关错误后重新打包版本号的修改 xcode打包导出ipa 第一步&#xff1…

没有accept还能建立tcp连接吗?

首先什么是accept&#xff1f;以下是常见的接收网络请求的伪代码 int main() {/*Step 1: 创建服务器端监听socket描述符listen_fd*/ listen_fd socket(AF_INET, SOCK_STREAM, 0);/*Step 2: bind绑定服务器端的IP和端口&#xff0c;所有客户端都向这个IP和端口发送和请求数…

3分钟,快速上手Postman接口测试

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

20230720----重返学习-小程序页面的初步完成

day-116-one-hundred-and-sixteen-20230720-小程序页面的初步完成 UI框架 weui - 微信小程序推荐的官方UI框架-很少人使用vant-weapp - 实际开发中常用的主流UI框架 vant-weapp安装 步骤一 通过 npm 安装 # 通过 npm 安装 npm i vant/weapp -S --production步骤二 修改 app.…

原型和原型链条、ES6、前后端交互Ajax

一、原型和原型链条 1.原型<script>/*原型 解决问题> 当你需要给实例对象添加方法> 直接书写在构造函数体内> 这个行为并不好> 我们的原型就是解决了这个问题 不好的原因> 当我把方法书写在构造函数体内> 每次创建实例的时候, 都会创建一个函数数据类…

vite4.x+vue3.x中使用装饰器语法,eslint校验不识别@的报错处理方法

在项目中&#xff0c;使用了pre-commit校验代码&#xff0c;eslint校验无法识别,导致一直无法提交代码&#xff0c;查找了资料&#xff0c;eslint版本过低&#xff0c;不能解决现在遇到的问题 最终正确的配置方法&#xff1a; 装饰器配置文件babel.config.js module.exports …

基于AutoEncoder自编码器的MNIST手写数字数据库识别matlab仿真

目录 1.算法理论概述 2.部分核心程序 3.算法运行软件版本 4.算法运行效果图预览 5.算法完整程序工程 1.算法理论概述 MNIST手写数字数据库是机器学习中常用的数据集&#xff0c;包含了0到9这10个数字的手写图片。本文介绍一种基于AutoEncoder自编码器的MNIST手写数字识别算…

数据库运维浅析

数据库是现代软件开发和数据管理的核心之一&#xff0c;它们允许我们存储和访问大量的数据&#xff0c;以及在需要时对数据进行修改和查询。在任何规模的组织中&#xff0c;数据库都是至关重要的&#xff0c;因此数据库运维是一个非常关键的领域。在这篇文章中&#xff0c;我们…

数字化项目管理如何推动项目快速上市?【洞见6】

AIGC时代的到来&#xff0c;标志着互联网从信息化的轻工业时代正式进入了互联网数字化的重工业时代。 随之迎来的是人工智能技术的广泛引用&#xff0c;如何在项目管理中应用也是一个挑战&#xff0c;因为的项目本身的特点就是变化、复杂。笔者在为了进行突破&#xff0c;开始不…

GPT-4逆天联网,微软Bing突然全面开放插件系统,文生图原生支持中文

文章目录 功能一览文生图&#xff1a;原生支持中文&#xff0c;但还有个「咒语」插件系统&#xff1a;搜索引擎版「App Store」网页检索&历史记录提取Edge浏览器深度融合联网版GPT-4&#xff0c;体验史诗级提升「微软」全宇宙 微软突然放炸弹&#xff0c;「ChatGPT搜索引擎…

读者问:省厅选调 和 阿里开发岗怎么选?

经常有小伙伴问编程君&#xff1a;程序员年龄大了&#xff0c;要不要转公务员&#xff1f; 于我而言&#xff0c;虽然能去个不错的互联网公司或者也可能进事业单位。但是一旦走上创业这个道路&#xff0c;真的就是不回路&#xff01; 很多时候别人问我如何做选择&#xff1f; 我…

AI竟能生成芯片了!GPT-4仅用19轮对话造出130nm芯片,攻克芯片设计行业巨大挑战HDL...

点击关注公众号&#xff1a;互联网架构师&#xff0c;后台回复 2T获取2TB学习资源&#xff01; 上一篇&#xff1a;Alibaba开源内网高并发编程手册.pdf 转自&#xff1a;新智元 编辑&#xff1a;Aeneas 润 【导读】GPT-4已经会自己设计芯片了&#xff01;芯片设计行业的一个老大…

国产开源大模型: 百亿参数“伶荔”,填补中文基础模型空白!

Datawhale开源 团队&#xff1a;深圳大学沈琳琳教授团队 Linly 伶荔说 中文语言大模型来啦&#xff01; 大数据系统计算技术国家工程实验室副主任、深圳大学计算机与软件学院沈琳琳教授团队主持的人工智能项目“伶荔(Linly)”于今天隆重推出“伶荔说”系列中文语言大模型。 该…

乐视实行四天半工作制,网友:还招人吗,我有个朋友想去!

作者 | 苏宓、出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 新春的第一个工作日&#xff0c;有一个别人家的公司登上了热搜&#xff0c;羡煞旁人&#xff0c;它就是乐视。 起因是因为#乐视开始实行每周四天半工作制#&#xff0c;所谓话少事大&#xff0c;在官宣…

2023年含:GPT-4的可免费使用语言模型AI平台推荐

文章目录 2023年可免费使用语言模型AI平台&#xff0c;含&#xff1a;GPT-4国际AIChatGPTNew BingSlackPOEVercelBardNotion AICraftYOU.com 国产AI文心一言通义千问 开源项目ColossalAIOpen Assistant其他 最后总结 2023年可免费使用语言模型AI平台&#xff0c;含&#xff1a;…

LSTM笔记

RNN, LSTM, GRU模型的作用, 构建, 优劣势比较,attention机: https://blog.csdn.net/sinat_28015305/article/details/109355828?ops_request_misc%257B%2522request%255Fid%2522%253A%2522167903492816800182195114%2522%252C%2522scm%2522%253A%252220140713.130102334..%252…

Typescript:类的装饰器

装饰器 装饰器为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式 装饰器是一种特殊类型的声明&#xff0c;它能够被附加到类声明&#xff0c;方法&#xff0c; 访问符&#xff0c;属性或参数上。 装饰器使用 expression这种形式&#xff0c;expression求值后必…

软考-系统架构设计师论文范文《论软件系统架构风格》

摘要: 本人于2016年1月参与浙江省某市公交集团“公交车联网一体化“项目&#xff0c;该系统为新能源营运车辆补贴监管、安全监控等方面提供全方位的软件支撑&#xff0c;在该项目组中我担任系统架构师岗位&#xff0c;主要负责整体架构设计与中间件选型.本文以该车联网项目为例…

大语言模型

LLM通常基于Transformer架构构建&#xff0c;这类模型依赖于自注意力机制。Transformer能够高效利用计算资源&#xff0c;使得训练更大规模的语言模型成为可能。 例如&#xff0c;GPT-4包含数十亿个参数&#xff0c;在大规模数据集上训练&#xff0c;在其权重中有效编码了大量…
最新文章