C语言趣味代码(一)

devtools/2024/9/24 12:33:13/

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.ppmy.cn/devtools/11735.html

相关文章

情感识别——情感计算的模型和数据集调查

概述 情感计算指的是识别人类情感、情绪和感觉的工作&#xff0c;已经成为语言学、社会学、心理学、计算机科学和生理学等领域大量研究的主题。 本文将概述情感计算的重要性&#xff0c;涵盖思想、概念和方法。 情感计算是皮卡德于 1997 年提出的一个想法&#xff0c;此后出…

复杂算子onnx导出(2): 将graph写入到onnx

前文通过自定义导出实现了trace, 然后将输入输出节点连接起来就形成了graph, 接下来利用得到的graph写入到onnx文件中。通过onnx.helper就可以构建出一个onnx文件,并且保存下来。 1. onnx.helper 示例 onnx结构中,包括了nodes,initializer ,inputs,outputs,graph。然后指定…

Fast DDS之Qos与Profiles

目录 XML profiles加载创建修改可配置内容 QosDeadlineQosPolicyDestinationOrderQosPolicyDurabilityQosPolicyDurabilityServiceQosPolicyEntityFactoryQosPolicyGroupDataQosPolicyHistoryQosPolicyLatencyBudgetQosPolicyLivelinessQosPolicyOwnershipQosPolicyOwnershipSt…

初入单元测试

单元测试&#xff1a;针对最小的功能单元(方法)&#xff0c;编写测试代码对其进行正确性测试 Junit可以用来对方法进行测试&#xff0c;虽然是有第三方公司开发&#xff0c;但是很多开发工具已经集成了&#xff0c;如IDEA。 Junit 优点&#xff1a;可以灵活的编写测试代码&am…

IDM2024破解版 IDM软件破解注册序列号 idm教程 idm序列激活永久授权 Internet Download Manager网络下载加速神器

你是不是感觉下载东西资源的时候&#xff0c;下载的非常慢&#xff0c;即便是五十兆的光纤依旧慢、是不是想下载网页上的视频但不知如何进行下载……这些问题是否一直在困扰着您&#xff0c;今日小编特意我大家带来了这款IDM 2024破解版。 众所周知&#xff0c;IDM是一款功能强…

【调制】π/4-DQPSK信号模型及其相关特性分析 【附MATLAB代码】

MATLAB代码 % pi/4-DQPSK modulation %输入一串数&#xff0c;输出经过差分并映射的I、Q两路数据 ​ function [I,Q]pi4_dqpskmod(data) ​ nlength(data)./2; data1data.*2-1; ​ Idatazeros(1,n); Qdatazeros(1,n); ​ ​ Idatadata1(1,1:2:2*n); %串并变换 Qdatadata1(…

【算法竞赛题目 题解收集】二分图最大匹配

1. hdu1068 Girls and Boys 传送门&#xff1a;https://vjudge.net.cn/problem/HDU-1068 t a g s tags tags&#xff1a;二分图最大匹配、最大独立集 题解&#xff1a;https://blog.csdn.net/m0_73500785/article/details/138076101?spm1001.2014.3001.5501 2. hdu1150 Mach…

统一SQL 支持Oracle number/decimal/dec/numeric转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 通过统一SQL&#xff0c;将Oracle中的numb…