C语言趣味代码(一)

C语言相关知识点的博客和大家分享完了,接下来我想开始数据结构相关的博客,在此之前呢,有的小伙伴问过我学完C语言的相关知识,我能干些什么呢?只有刷题吗?这不禁让我反思:在我们学习的过程中,我们所有学习时用到的书籍都是围绕某一知识点介绍、拓展,千篇一律的示例代码,好像从没出现一些新颖的代码。所以我想用3篇左右的博客跟大家分享一下用我们学过的知识实现的有趣代码,然后再开始后面的数据结构的博客。

1. 心算训练

什么是心算呢?心算是一种在不使用纸张或任何其他非思维工具的情况下解决数学问题的技能。心算能力是指仅用头脑进行数学计算的能力。无需计算器等外部工具的帮助。虽然在现代世界中这似乎是一项无用的技能,但它实际上非常有用,并且对于提高解决问题和决策的技能大有帮助。下面我们先介绍可能会用到的相关函数,然后再进行实现。

1.1 操纵时间

首先我们编写一个能够操纵时间,显示动态画面的程序:

#include<stdio.h>
#include<time.h>
int sleep(unsigned long x)
{clock_t c1 = clock(), c2;do {if ((c2 = clock()) == (clock_t)-1){return 0;}} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC<x);return 1;
}
int main()
{int i;clock_t c;for (i = 10; i > 0; i--){printf("\r%2d", i);fflush(stdout);sleep(1000);}printf("\r\aEND! \n");c = clock();printf("程序从开始到结束运行了%.1f秒\n", (double)c / CLOCKS_PER_SEC);return 0;
}

因为我不太会电脑录制,就给大家看一下最终结果吧,感兴趣的可以自己试试。

在这个程序中我们使用了clock函数用来求程序开始运行到结束所花费的时间。

函数名clock函数
头文件#include<time.h>
格式clock_t clock(void)
功能求处理器调用某个进程所花费的时间
返回值从定义与程序启动相关的编程环境的时间点起,用处理系统的最佳值逼近返回程序占用处理器的时间。为了以秒为计量单位,必须用本函数的返回值除以CLOCK_FER_SEC宏的值,如果无法获取处理器调用该进程花费的时间,或无法显示数值是,就返回(clock_t)-1。

可以使用<time.h>头文件吧返回值的类型clock_t型定义成等同于算术类型,clock_t主要等同于那种类型(unsigned,unsigned long....)要取决于编程环境。在某些环境中clock_t型并不等同于unsigned型,程序在这些编程环境中,比一定能顺畅运行。除此之外,因为不同的硬件和OS会导致时钟的精准度也不同,所以clock_t型表示数值的单位也取决于编程环境,因此通常用<time.h>头文件定义CLOCK_FER_SEC这一对象宏,CLOCK_FER_SEC直接翻译过来就是“每秒的时钟数”。如果时钟的精度在0.001秒,那么一秒内就有1000个时钟,这个宏的值就定义为1000。

#define CLOCK_FER_SRC 1000//定义示例,根据编程环境的不同有所差距

在上面的程序中,用一位小数的实数值,表示程序启动后花费的时间。

c = clock();
printf("程序从开始到结束运行了%.1f秒\n", (double)c / CLOCKS_PER_SEC);

上面这部分代码把c强制类型转换成了double型,来求出经过的秒数,这是因为“整数/整数”的运算中会舍去小数部分。另外,因为clock函数返回的值只用于求经过的时间,所以不加入变量c也能实现(这样一来变量c也就可以省去了):

c = clock();
printf("程序从开始到结束运行了%.1f秒\n", (double)clock() / CLOCKS_PER_SEC);

讲了如何计算程序启动后经过的时间,下面来教大家如何计算处理特定部分所需要的时间。因为程序不接受错误的答案,所以在回答正确之前程序都不会改变。我们试着实现一下:提示的问题是要把三个三位数的整数相加,输出答案后,画面上会显示解题共花费了多长时间:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main()
{int a, b, c;//要进行加法运算的数值int x;//读取的值clock_t start, end;//开始时间和结束时间double req_time;//所需时间srand(time(NULL));a = 100 + rand() % 900;b = 100 + rand() % 900;c = 100 + rand() % 900;printf("%d+%d+%d的计算结果是多少:", a, b, c);start = clock();while (1){scanf("%d", &x);if (x == a + b + c)break;printf("\a回答错误!\n请重新输入");}end = clock();req_time = (double)(end - start) / CLOCKS_PER_SEC;printf("用时%.1f秒", req_time);if (req_time > 30.0)printf("花费时间太长了\n");if (req_time > 15.0)printf("还不错\n");elseprintf("好厉害\n");return 0;
}

我们运行一下来看看吧(我算的有点慢):

这里面的while语句是为了不接受错误答案而设置的循环,因为控制表达式的是1,所以循环会一直执行下去,当回答正确时,程序会通过break语句强行中断while循环。如果不想使用brak语句,也可以使用下面的do..while语句来中断循环:

do
{scanf("%d",&x);if(x!=a+b+c)printf("\a回答错误!\n请重新输入:");
}while(x!=a+b+c);

 在上面的代码中,为了将处理暂停一段时间,我们使用了sleep函数:

int sleep(unsigned long x)
{clock_t c1 = clock(), c2;do{if ((c2 = clock()) == (clock_t)-1){return 0;}} while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);return 1;
}

首先程序一开始调用了clock函数,把程序启动后经过的时间存入c1,然后运行do语句,在每次循环时调用clock函数,把获取的数值赋给c2。程序中while语句括号里面会以毫秒为单位表示sleep函数开始运行后经过的时间,当这个数值大于等于x时,通过do语句进行的循环就结束了。上文所说,clock函数“如果无法获取处理器调用该进程花费的时间,或无法显示数值是,就返回(clock_t)-1”。这里是把int型的整数值-1强制类型转换成clock_t类型后的值,绝不是“clock_t-1后的值”。当clock函数返回表示错误的-1时,sleep函数会通过返回0来通知调用发生了问题。注意:sleep函数会占用CPU,与其说“运行函数花了多长时间”,但不如说“sleep函数让CPU这个大脑持续运行了多少时间”。

1.2 最终实现

这是一个把3个3位数连续相加的心算训练程序,程序最后会显示进行10次心算所需要的时间:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int main()
{int stage;//次数int a, b, c;int x;int n;//空白的宽度clock_t start, end;srand(time(NULL));printf("心算训练开始!\n");start = clock();for (stage = 0; stage < 10; stage++){a = 100 + rand() % 900;b = 100 + rand() % 900;c = 100 + rand() % 900;n = rand() % 15;printf("%d%*s+%*s%d%*s+%*s%d=", a, n, "", n, "", b, n, "", n, "", c);do{scanf_s("%d", &x);if (x == a + b + c)break;printf("\a回答错误!\n请重新回答");} while (1);}end = clock();printf("一共用时%.1f秒", (double)(end - start) / CLOCKS_PER_SEC);return 0;
}

其中,我们把空白字符的个数n定位0~14的随机数。我们命令printf函数“至少用n位数表示空的字符串”,程序就会显示n个空白字符串。数值间留有空白,可以训练我们的心算能力。

2. 猜拳游戏

现在我们要编写一个提供两位玩家对战的“猜拳游戏”。当然,这里所说的“两位玩家”是指计算机和玩家,即游戏采用人机对战的模式。:

2.1 流程分析

  1. 确定计算机要出的手势。
  2. 显示“石头剪刀布”,然后玩家输入自己要出的手势。
  3. 进行输赢判断。,显示结果。
  4. 询问是否继续,如果玩家希望继续,就回到1。

下面我们详细设计一下各个步骤:

1.用随机数确定计算机所出的手势:

之所以要先确定计算机出的手势,再读取玩家的手势,是为了避免计算机作弊。

2.如果用“石头”,“剪刀”,“布”的字符串来进行手势输入,可能会产生输入错误,例如一不小心打错字,变成“势头”,“见到”等。因此我们把“石头”,“剪刀”,“布”这三个手势分别对应数字0,1,2(类型设为int型)。如果玩家的手势和计算机的手势能用相同的数值表示出来,就保持了一致性,会方便,这样一来,也确定了在1的设计中未解决的手势的数值。

3.根据计算机和玩家的手势判断胜负:

此处使用变量human和comp来分别表示玩家和计算机的手势,下面为手势和胜负的关系:

平局情况:

humancomphuman-comp(human-comp+3)%3
0000
1100
2200

玩家失败情况:

humancomphuman-comp(human-comp+3)%3
02-21
1011
2111

 玩家胜利的情况:

humancomphuman-comp(human-comp+3)%3
01-12
12-12
2022

上面的3个表格中汇总了双方的手势数值、human减去comp后的值、判断表达式(human-comp+3)%3的值。如果human和comp的值相等就算作“平局”,此时human-comp的值为0。失败和胜利的情况同理。

2.2 程序的实现

2.2.1 用switch语句实现

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{int human;//玩家的手势int comp;//电脑的手势int judge;//胜负int retry;//再来一次?srand(time(NULL));printf("猜拳游戏开始!\n");do{comp = rand() % 3;printf("\n\a石头剪刀布   (0)石头(1)剪刀(2)布:");scanf("%d", &human);printf("我出的是:");//显示计算机出的手势switch (comp){case 0:printf("石头");break;case 1:printf("剪刀");break;case 2:printf("布");break;}printf("。\n");judge = (human - comp + 3) % 3;switch (judge){case 0:printf("平局");break;case 1:printf("你输了");break;case 2:printf("你赢了");break;}printf("还要再来一次吗?(0)否(1)是");scanf("%d", &retry);} while (retry == 1);return 0;
}

我们来运行看一下:

2.2.2 让计算机“后出” 

为了让计算机赢,我们可以让计算机比玩家后出。具体实现代码 :

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{int i;int human;int comp;int judge;int retry;char* hd[] = { "石头","剪刀","布" };printf("猜拳游戏开始!\n");do{do {printf("\n\a石头剪刀布   ");for (i = 0; i < 3; i++)printf("(%d)%s", i, hd[i]);printf(":");scanf("%d", &human);} while (human < 0 || human>2);comp = (human + 2) % 3;//计算机后出printf("我出%s,你出%s.\n", hd[comp], hd[human]);judge = (human - comp + 3) % 3;switch (judge){case 0:printf("平局\n");break;case 1:printf("你输了\n");break;case 2:printf("你赢了\n");break;}printf("再来一次吗?   (0)否(1)是");scanf("%d", &retry);} while (retry == 1);return 0;
}

运行一下看看结果:

这个程序可以拿给朋友玩,在旁边看他一直输。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/823172.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

远程DCS监控

在数字化、智能化的浪潮中&#xff0c;工业控制系统正迎来前所未有的变革。分布式控制系统&#xff08;DCS&#xff09;作为工业自动化领域的核心&#xff0c;其稳定运行对于企业的生产效率和安全至关重要。而远程DCS监控作为实现工业自动化、智能化管理的关键一环&#xff0c;…

【wpf】ObservableCollection 跨线程报错问题

背景 ObservableCollection 我们之前介绍过他和List的区别。ObservableCollection 的好处在于&#xff0c;当集合发生变化时&#xff0c;能发送通知通知界面发生相应的更改。但是ObservableCollection 有个弊端。无法在非UI线程中访问。 要么就是通知失效了&#xff0c;要么就…

MySQL修改数据表的结构

创建数据库 -- create database 创建的数据库名; create database test; 这里创建了一个名为 test 的数据库 选择需要使用的数据库 -- use 数据库名; use test; 这里使用 test 数据库 创建数据表 -- create table 表名(字段名1 数据类型(长度) 约束,字段名2 数据类型(长…

【强化学习的数学原理-赵世钰】课程笔记(九)策略梯度方法(Policy Gradient Method)

目录 一.policy gradient 的基本思路&#xff08;Basic idea of policy gradient&#xff09; 二.定义最优策略的 metrics&#xff0c;也就是 objective function 是什么 三.objective function 的 gradient 四.梯度上升算法&#xff08;REINFORCE&#xff09; 五.总结 上…

企业常用命令(touch/别名/重定向/Linux字符)7368字详谈

企业高薪思维&#xff1a; 企业&#xff08;工作/学习中&#xff09;操作前备份&#xff0c;操作后检查 最小化原则 1.安装软件最小化 2.参数选项最小化 3.登录用户权限最小化&#xff08;不用root登录&#xff09; 要想成功/学习上/工作上 永远比别人多做一点点&#xff08;别…

幻兽帕鲁老板公开发声:腾讯正在制作幻兽帕鲁克隆版

昨天&#xff0c;Pocketpair的老板出来指责中国游戏公司抄袭了他们的游戏Palworld&#xff0c;说这简直是太不可思议了。 Pocketpair的CEO Takuro Mizobe发布了一个叫Auroria的游戏的截图&#xff0c;然后说&#xff1a;“腾讯正在制作Palworld的克隆游戏&#xff01;在中国&a…

Python根据主播直播时间段判定订单销售额归属

写在前面&#xff1a;最近在群里看到一个这样的直播电商的场景觉得还是挺有趣的&#xff0c;于是就想用Python来实现。 需求描述&#xff1a;根据主播直播时间段结合销售订单的付款时间判断所属销售的归属 生成主播在线直播时间段数据 from datetime import datetime, time…

zabbix监控配置(添加主机、主机组和添加监控项等)

zabbix监控配置 文章目录 zabbix监控配置1.添加主机组2.添加主机&#xff08;linux&#xff09;3.添加主机&#xff08;windows&#xff09;4.监控项配置&#xff08;通过模板添加&#xff09;5.监控项配置&#xff08;手动添加&#xff09; 1.添加主机组 2.添加主机&#xff0…

学习Rust的第5天:控制流

Control flow, as the name suggests controls the flow of the program, based on a condition. 控制流&#xff0c;顾名思义&#xff0c;根据条件控制程序的流。 If expression If表达式 An if expression is used when you want to execute a block of code if a condition …

自定义vue-cli 实现预设模板项目

模板结构 主要包括四个部分&#xff1a; preset.jsonprompts.jsgenerator/index.jstemplate/ 项目最终结构 preset.json preset.json 中是一个包含创建新项目所需预定义选项和插件的 JSON 对象&#xff0c;让用户无需在命令提示中选择它们&#xff0c;简称预设&#xff1b;…

openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置

文章目录 openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置265.1安装openEuler操作系统265.2 修改操作系统内核PAGESIZE为64KB。265.3 关闭CPU中断的服务irqbalance openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置 本…

2011年认证杯SPSSPRO杯数学建模C题(第二阶段)你的爱车入保险了吗全过程文档及程序

2011年认证杯SPSSPRO杯数学建模 C题 你的爱车入保险了吗 原题再现&#xff1a; 近几年&#xff0c;国内汽车销售市场异常火爆&#xff0c;销售量屡创新高。车轮上的世界&#xff0c;保险已经与我们如影随形。汽车保险&#xff0c;简称车险&#xff0c;是指对机动车辆由于自然…

计算机考研都将采用408!?

这个根本不可能&#xff0c;高考还没做到全国统一考试呢 每个学校对于计算机招生的需求是不一样的&#xff0c;比如清华大学&#xff0c;专业课912&#xff0c;算的上是最难的计算机专业课了&#xff0c;那他为什么搞这么难啊&#xff0c;还不是因为那群敢考清华的卷王们太变态…

Python数据结构【二】查找

前言 可私聊进一千多人Python全栈交流群&#xff08;手把手教学&#xff0c;问题解答&#xff09; 进群可领取Python全栈教程视频 多得数不过来的计算机书籍&#xff1a;基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。 &#x1f680;&a…

C++奇迹之旅:构造函数

文章目录 &#x1f4dd;类的6个默认成员函数&#x1f320; 构造函数&#x1f309; 概念&#x1f309;特性&#x1f309;三种默认构造函数 &#x1f6a9;总结 &#x1f4dd;类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&am…

【重磅开源】一款可以生成SpringBoot+Vue代码的轻量级项目

基于SpringBootVue3开发的轻量级快速开发脚手架 &#x1f341;项目简介 一款通用的前、后端项目模板 一款快速开发管理系统的项目 一款可以生成SpringBootVue代码的项目 一款持续迭代的开源项目 一个程序员的心血合集 度过严寒&#xff0c;终有春日&#xff…

Nginx内存池相关源码剖析(一)总览

剖析nginx的内存池源码&#xff0c;讲解原理实现以及该内存池设计的应用场景 介绍 Nginx内存池是Nginx为了优化内存管理而引入的一种机制。在Nginx中&#xff0c;每个层级&#xff08;如模板、TCP连接、HTTP请求等&#xff09;都会创建一个内存池进行内存管理。当这些层级的…

Linux下redis的安装过程与配置详细教程【5.0.5为例子】

Linux下redis的安装过程与配置方法【5.0.5为例子】 下载redis redis下载地址 https://download.redis.io/releases/ 也可以自行去官网下载 提示&#xff1a;此处安装的为redis-5.05的版本 上传redis安装包(我的安装目录为/data/tool/redis-5.0.5) 创建目录/data/local/tool并…

Day20-【Java SE高级】单元测试 反射 注解 动态代理

一、单元测试 就是针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试。 1. 咱们之前是如何进行单元测试的?有啥问题? 只能在main方法编写测试代码&#xff0c;去调用其他方法进行测试。无法实现自动化测试&#xff0c;一个方法测试失败&#xff0c;可能…

Day 23 669. 修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树 总结篇

修剪二叉搜索树 给定一个二叉搜索树&#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&#xff0c;所以结果应当返回修剪好的二叉搜索树的新的根节点。 ​ 最直接的想法&#xff0…