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,一经查实,立即删除!

相关文章

Chromium中代理服务器的配置、使用与认证过程

文章目录 获取与解析代理配置选择代理服务器Chromium中的代理服务器源码文件Chromium将流量导向代理服务器的过程代理服务器认证过程代理连接与直接连接的区别关于TCP隧道总结 在Chromium浏览器中&#xff0c;代理服务器的配置和使用是由 ProxyService类来管理的&#xff0c;它…

远程DCS监控

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

【香瓜创业】定位 (2024.04.17)

自从17年4月份开始辞职创业&#xff0c;已经刚满7年了。今天与大家分享一次我与李总的争论内容。 我跟李总争吵的次数并不多&#xff0c;因为大部分情况下他的思维对我是降维打击&#xff0c;但这次我坚信我没错&#xff0c;所以争吵到两人都说了气话&#xff0c;觉得三…

【wpf】ObservableCollection 跨线程报错问题

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

对单片机的一点理解

前言 大一时学过一段时间的51单片机&#xff0c;后面就一直研究STM32和算法&#xff0c;最近工作搞51单片机有半年了&#xff0c;有一些自己的想法&#xff0c;跟公司的工程师也探讨了一些&#xff0c;结合聊天记录&#xff0c;写了这篇博客&#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;别…

milvus querycoord启动源码分析

querycoord启动源码分析 结构体 // Server is the grpc server of QueryCoord. type Server struct {wg sync.WaitGrouploopCtx context.ContextloopCancel context.CancelFuncgrpcServer *grpc.ServerserverID atomic.Int64grpcErrChan chan error// 是一个接口类…

DDD领域设计基础

1概述 作为架构师&#xff0c;我们在业务建模的时候不能完全凭经验、感觉&#xff0c;我们还得有一套方法论&#xff0c;DDD领域驱动恰巧可以作为业务建模的方法论来使用。 2 为什么要使用DDD 2.1 为什么需要DDD 复杂系统设计&#xff1a;系统多&#xff0c;业务逻辑复杂&a…

ABeam德硕|旗下艾宾信息技术开发上海、西安、大连三地校招信息公开,期待您的加入!

寻人启事 想要找到你&#xff01; 关于我们 ABeam Consulting全球 ABeam Consulting集团成立于1981年&#xff0c;总部位于日本东京&#xff0c;历经40余年的发展&#xff0c;先后在中国、韩国、泰国、新加坡、英国、德国、美国等全球多个国家和地区设立了服务网点&#xff0…

Python和R概率统计算法建模评估气象和运动

&#x1f3af;要点 概率统计数学&#xff1a;&#x1f3af;Python和R计算和算法实现气象学&#xff1a; 计算和可视化&#xff1a;&#x1f3af;全球陆地-海洋平均年平均表面温度&#xff1a;&#x1f58a;直方图温度异常&#xff0c;&#x1f58a;显示分位数-分位数&#xff…

使用Socket实现局域网内聊天室

需要提前了解的Socket知识点&#xff1a; Client端输入的IP都是Server所在电脑的IPServer最好设置0.0.0.0这样无论迁移到哪个电脑上&#xff0c;都是那台电脑的IPClient和Server必须在同一个局域网之下&#xff0c;否则不能通信&#xff1b;如果要实现跨局域网通信&#xff0c…

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

昨天&#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性能调优测试指导-操作系统配置 本…

绩效考核:关键成功因素法(CSF)

绩效考核是企业管理的核心环节&#xff0c;其目的是为了确保员工的工作表现符合组织的目标和期望。然而&#xff0c;传统的绩效考核方法往往只关注员工的业绩和产出&#xff0c;而忽略了员工的能力和潜力。关键成功因素法&#xff08;CSF&#xff09;作为一种新型的绩效考核方法…