C语言中的趣味代码(五)

我想以此篇结束关于C语言的博客,因为在C语言拖得越久越不能给大家带来新的创作,在此我也相信大家对C语言已经有了一个新的认知。进入正题,在这一篇中我主要编一个“英语单词练习小程序”来给大家展开介绍,从测试版逐步改良,每一步详细讲解让大家能够对学过的知识再有一个全新的认知。

1. 英语练习软件

1.1 单词显示软件

在编写英语学习软件之前,我们先来编写一个只能随机显示单词的程序,我们看下面的代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define QNO 12//单词的数量
char* cptr[] = { "动物","汽车","花","家","桌子","书","椅子","爸爸","妈妈","爱","和平","杂志"};
char* eptr[] = { "animal","car","flower","house","desk","book","chair","father","mother","love","peace","magazine"};
int main()
{int nq, pq;//题目编号和上一次的题目编号int sw;//选择中文英文int retry;//是否接着尝试srand(time(NULL));pq = QNO;do{do {nq = rand() % QNO;} while (nq == pq);sw = rand() % 2;printf("%s\n", sw ? eptr[nq] : cptr[nq]);pq = nq;printf("再来一次吗?0-否/1-是:");scanf("%d", &retry);} while (retry == 1);return 0;
}

我们简单运行一下看看效果,然后再这个基础上进行改良:

 程序运行。从“动物”,“汽车”.....以及与这些词对应的英语单词“animal”,"car"...这12组共24个单词中随机选出的单词被显示出来,用于存放指向单词字符串的指针的数组有2个,中文单词是cptr,英文单词的数组是eptr,我们把这两个数组的下标成为单词的“编号”。为了随机选择单词,我们需要用到2个变量nq和sw,这2个变量的值都是随机的。变量nq表示要显示的单词的编号。nq的值设为大于等于0小于QNO的随机数。变量nq设定与上一次现实的单词的编号pq不同的值,所以同一个编号的单词不会被连续选中。变量sw表示显示中文或者英文。sw的值为0时显示为中文单词,为1时显示英语单词,值0和1设为随机数。

1.2 向单词学习软件扩展

在刚才的程序中只能显示单词,现在我们要显示单词的时候提供选项,共学习者选择,学习者选完程序进行正误判断。我们呢来实现一下:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define QNO 12
#define CNO 4
char* cptr[] = { "动物","汽车","花","家","桌子","书","椅子","爸爸","妈妈","爱","和平","杂志"};
char* eptr[] = { "animal","car","flower","house","desk","book","chair","father","mother","love","peace","magazine"};
void print_cand(const int c[], int sw)//显示选项
{int i;for (i = 0; i < CNO; i++)printf("(%d)%s ", i, sw ? cptr[c[i]] : eptr[c[i]]);printf(":");
}
int make_cand(int c[], int n)//生成选项并返回正确答案的下标
{int i;c[0] = n;for (i = 1; i < CNO; i++)c[i] = rand() % QNO;return 0;
}
int main()
{int nq, pq;int na;int sw;int retry;int cand[CNO];srand(time(NULL));pq = QNO;do{int no;do{nq = rand() % QNO;} while (nq == pq);na = make_cand(cand, nq);sw = rand() % 2;printf("哪一个是%s?\n", sw ? eptr[nq] : cptr[nq]);do{print_cand(cand, sw);scanf("%d", &no);if (no != na)printf("\a回答错误。");} while (no != na);printf("回答正确。");pq = nq;printf("再来一次吗?0-否/1-是");scanf("%d", &retry);} while (retry == 1);return 0;
}

我们来运行一下看看效果:

 决定用于出题的单词的方法和上一个程序相同,在这个程序中追加了两个函数,下面我们就一起来学习一下这两个函数。

  1. 函数print_cand:显示选项
  2. 函数make_cand:生成选项

函数print_cand用于显示选项,它将接受下面两个参数:

 c:存有选项编号的数组

参数c接收的是存有选项单词编号的数组。

sw:题目的语言(英文/中文)

参数sw的值表示用来出题的单词的语言。若用的是英语,则sw为1,若为中文,则sw为0。for语句 中则显示与题目相反的单词。

函数make_cand用于生成要提示的4个选项,他将接收下面两个参数:

c:存有选项编号的数组

参数c接收的是存有选项单词编号的数组。

n:题目(正确答案)的编号

参数n接收的是正确答案(用于出题的单词)的编号。

运行程序我们会发现,这个程序存在两个隐藏问题:正确答案一定位于选项开头的位置,这让一来学习者就知道答案了。由于后面3个选项设为大小等于0小于QNO的随机数,因此可能会生成相同的随机数值,此时就会出现重复的选项。

1.3 生成选项(改良版本)

为了解决上面程序中的隐藏问题,我们可以将make_cand函数修改成下面这样:

int make_cand(int c[],int n)
{int i,j,n;c[0]=n;for(i=1;i<CNO;i++){do{n=rand()%QNO;for(j=0;j<i;j++)if(c[j]==n)break;}while(i!=j);c[i]=n;}j=rand()%CNO;if(j!=0)swap(int,c[0],c[j]);return j;
}

此项的操作和上一个程序相同,把正确答案的编号n赋给数组的开头元素c[0]。这个for语句负责生成剩下的3个选项,把变量i的值增量给1,2,3,进行3次循环。这里和前面程序的不同之处在于,for语句的循环体里面加入了do...while语句,形成了二重循环的结构,在内侧的do...while语句的作用下,程序会一直重复生成随机数直到出现没有选过的选项值为止,这样一来就避免了选项出现重复,接下来我们要做的是移动正确答案,首先生成随机数0~3,把该值设为j,如果生成的随机数刚好为0,那么就变成了c[0]和c[0],这是程序会通过if语句跳过交换处理(正确答案的移动操作)。此外,用随机数生成的j的值的范围必须设为0~3而不能是1~3,因为正确答案绝不能位于开头。

1.4 单词文件的读取

如果用于出题的单词只有12个,学习者很容易就能记住,下面我们来让程序能够处理更多的单词。如果单词达到了一定的数量,那么就应该提供一个单词专用文件,以便追加和删除单词,但是在这种情况下,程序方面单词数量就会变得不明确,也就无法把单词存入“数组”,因此在声明时数组的元素个数必须是已知的,因此我们需要在运行程序时为任意元素个数的数组动态分配空间。

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#define CNO 4
#define swap(type,x,y) do{type t=x;x=y;y=t;}while(0)
int QNO;
char** cptr;
char** eptr;
void print_cand(const int c[], int sw)//显示选项
{int i;for (i = 0; i < CNO; i++)printf("(%d)%s ", i, sw ? cptr[c[i]] : eptr[c[i]]);printf(":");
}
int make_cand(int c[], int n)
{int i, j, x;c[0] = n;for (i = 1; i < CNO; i++){do{x = rand() % QNO;for (j = 0; j < i; j++)if (c[j] == x)break;} while (i != j);c[i] = x;}j = rand() % CNO;if (j != 0)swap(int, c[0], c[j]);return j;
}
int read_tango()
{int i;FILE* fp;if ((fp = fopen("TANGO.txt","r")) == NULL)return 1;fscanf(fp, "%d", &QNO);if ((cptr = calloc(QNO, sizeof(char*))) == NULL)return 1;if ((eptr = calloc(QNO, sizeof(char*))) == NULL)return 1;for (i = 0; i < QNO; i++){char etemp[1024];char ctemp[1024];fscanf(fp, "%s%s", etemp, ctemp);if ((eptr[i] = malloc(strlen(etemp) + 1)) == NULL)return 1;if ((cptr[i] = malloc(strlen(ctemp) + 1)) == NULL)return 1;strcpy(eptr[i], etemp);strcpy(cptr[i], ctemp);}fclose(fp);return 0;
}
int main()
{int i;int nq, pq;int na;int sw;int retry;int cand[CNO];if (read_tango() == 1){printf("\a单词获取失败。\n");return 1;}srand(time(NULL));pq = QNO;do{int no;do{nq = rand() % QNO;} while (nq == pq);na = make_cand(cand, nq);sw = rand() % 2;printf("哪一个是%s?\n", sw ? eptr[nq] : cptr[nq]);do{print_cand(cand, sw);scanf("%d", &no);if (no != na)printf("回答错误。");} while (no != na);printf("回答正确。");pq = nq;printf("再来一次吗?0-否/1-是:");scanf("%d", &retry);} while (retry == 1);for (i = 0; i < QNO; i++){free(eptr[i]);free(cptr[i]);}free(eptr);free(cptr);return 0;
}

我们来运行一下看看效果:

用于存放中文单词的cptr和用于存放英语单词的eptr这两个指针指向的都是指向char型的指针,即指向“指向已动态分配的字符串的”指针的数组。我们准备的单词数据是以“TANGO”为名称的文本文档形式,如下图:

第一行写入了一个整数值表示单词数量,从第二行起准备了英语单词和对应的中文释义,函数read_tango用于打开文本文件“TANGO”,并在分配存储空间的同时读取单词,当文件无法打开时或者存储空间分配失败时返回1,正常读取时返回0。在这里读取文件会常遇到一个问题那就是中文会出现乱码的情况,如下图:

那怎么解决这种问题呢?我只需要找到文本文件点击另存为,将其编码改为ASNI即可:

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

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

相关文章

【无标题】测试下目录间距

文章目录 前言一、Java基础题1、Java语言的三大特性2、JDK 和 JRE 有什么区别3、Java基本数据类型及其封装类4、说明一下public static void main(String args[])这段声明里关键字的作用5、 与 equals 的区别6、Java语言的三大特性7、Java语言的三大特性8、Java语言的三大特性9…

OpenHarmony实战开发-属性样式动画

在关键帧&#xff08;Keyframes&#xff09;中动态设置父组件的width和height&#xff0c;实现组件变大缩小。子组件设置scale属性使父子组件同时缩放&#xff0c;再设置opacity实现父子组件的显示与隐藏。 <!-- xxx.hml --> <div class"container"><…

OGG extract进程占据大量虚拟内存导致服务器内存异常增长分析

现象 oracle服务器一节点内存&#xff0c;一个月来持续升高&#xff0c;近一月上涨10%左右。 问题分析 OS内存使用情况 使用内存最大的10个进程如下&#xff0c;PID为279417占用最大的内存。 查询279417&#xff0c;发现是ogg相关进程。 发现ogg的extract进程占用了大量的虚拟内…

三个目前主流的计算机视觉软件

计算机视觉是人工智能的一个重要分支&#xff0c;它涉及到使计算机能够理解和解释图像和视频数据。近年来&#xff0c;计算机视觉领域取得了显著的进展&#xff0c;尤其是在深度学习的帮助下。尽管如此&#xff0c;将计算机视觉的能力直接与人类的视觉能力进行比较并不完全准确…

vite打包配置

目录 minify默认是esbuild&#xff0c;不能启动下面配置 使用&#xff1a; plugins: [viteMockServe({mockPath: mock})]根目录新建mock/index.ts. 有例子Mock file examples&#xff1a;https://www.npmjs.com/package/vite-plugin-mock-server 开发环境生产环境地址替换。根…

P9586 「MXOI Round 2」游戏

「MXOI Round 2」游戏 题目描述 小 C 和小 D 正在玩一款蒸蒸日上的游戏。 这款游戏共有 3 3 3 种手牌&#xff1a;杀、闪、斩。他们的用途分别如下&#xff1a; 杀&#xff1a;对对方使用&#xff0c;对方需要使用一张闪&#xff0c;否则对方输掉游戏&#xff1b;或回应对方…

spark实验求TOP值

实验1&#xff1a;求TOP值 已知存在两个文本文件&#xff0c;file1.txt和file2.txt&#xff0c;内容分别如下&#xff1a; file1.txt 1,1768,50,155 2,1218, 600,211 3,2239,788,242 4,3101,28,599 5,4899,290,129 6,3110,54,1201 7,4436,259,877 8,2369,7890,27 fil…

记录一些容易遗忘的东西

文章目录 native、sync 修饰符this.$nextTick native、sync 修饰符 native &#xff1a;在对子组件使用 click 的时候若不使用该修饰符&#xff0c;那么就不能执行点击事件&#xff0c;会被判断为子向父组件传的值sync &#xff1a; 类似于 v-model 的响应式修饰符&#xff0c…

活性炭复合纳米纤维膜

活性炭复合纳米纤维膜是一种结合了活性炭和纳米纤维技术的新型复合材料。这种材料通常通过特定的制备工艺&#xff0c;如静电纺丝技术&#xff0c;将活性炭纳米纤维与其他材料&#xff08;如TiO2、聚合物等&#xff09;结合在一起&#xff0c;形成具有良好结构和功能的薄膜。 活…

白帽子讲Web安全读书笔记

-- 书的结构 4大篇共18章&#xff1a; 我的安全世界观&#xff1a;安全历史->作者对安全的看法与态度->思考问题的方式和做事的方法客户端脚本攻击&#xff1a;对浏览器的深入理解将有助于做好该解决方案服务端应用安全&#xff1a;网站安全建设之初的重点处理问题大安…

UDP!!!

UDP!!! 一 : 传输层的协议:二 : UDP2.1 UDP长度2.2 UDP校验和2.2.1 : 为什么会出现传输出错的情况??2.2.3: 对数据进行校验的方式CRCmd5 三 : UDP的适用场景 一 : 传输层的协议: 传输层的协议有UDP,TCP UDP:无连接,不可靠传输,面向数据报,全双工 TCP:有连接,可靠传输,面向字…

nvm 切换 Node 版本失败

创建vue3项目时&#xff0c;需要切换到更高版本的 node&#xff0c;于是使用 nvm (node 包版本管理工具)进行版本切换 切换版本时&#xff0c;显示成功&#xff0c;但再次查看当前 node 版本时&#xff0c;发现没切换过来。 解决方法&#xff1a; where node 查看node的安装…

vue路由(路由基本使用,传参,多级路由)

目录 vue-router简介路由配置和使用嵌套&#xff08;多级&#xff09;路由路由传参方式1&#xff1a;路由的query参数方式2&#xff1a;路由的params参数props配置 命名路由取消路由组件在前进后退 vue-router简介 vue的一个插件库&#xff0c;专门用来实现SPA应用 路由配置…

2024年这样做抖音小店,操作简单,起店稳定!

大家好&#xff0c;我是电商糖果 不少朋友说跟糖果抱怨过&#xff0c;说抖音小店越来越难做了。 平台的规则越来越多&#xff0c;商家运营店铺的时候&#xff0c;很容易出现违规预警。 糖果是2020年开始做的抖音小店&#xff0c;现在已经经营了多家小店。 实话实说确实比之…

MySQL面试题:经典面试题之“B+树”

在MySQL数据库领域&#xff0c;B树是一个经典的数据结构&#xff0c;它在数据库索引中发挥着重要的作用。本文将深入探讨B树的概念、特点以及在MySQL中的应用&#xff0c;帮助程序员更好地理解和掌握这一重要的数据结构。 1. B树的概念 B树是一种平衡的多路搜索树&#xff0c…

行为型设计模式

一、责任链设计模式 &#xff08;一&#xff09;概念 使多个对象都有机会处理同一个请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 &#xff08;二&#xf…

Gone框架介绍1 - 在go语言上实现依赖注入,Gone是如何实现的?

文章目录 Goner的定义在Gone中是如何完成依赖注入的&#xff1f; 我在两年前实现了一个Golang的依赖注入框架&#xff0c;并且集成了gin、xorm、redis、cron、消息中间件等功能&#xff0c;自己觉得还挺好用的&#xff1b;之前一直没有时间写文档推广&#xff0c;现在"毕业…

vscode相关插件使用----持续更新中

一、VSCode&#xff08;Visual Studio Code&#xff09;常用的插件&#xff1a; Vetur/Volar&#xff1a;用于Vue.js项目的开发&#xff0c;提供语法高亮、智能感知等功能。ESLint&#xff1a;用于JavaScript代码的语法检查和风格检查&#xff0c;支持多种编码规范。Prettier …

OpenHarmony实战开发-如何实现绘制路径、并填充颜色实现饼状图效果。

Svg组件绘制路径时&#xff0c;通过Path中的M&#xff08;起点&#xff09;、H&#xff08;水平线&#xff09;、a&#xff08;绘制弧形到指定位置&#xff09;路径控制指令&#xff0c;并填充颜色实现饼状图效果。 <!-- xxx.hml --> <div class"container"…

MongoDB聚合运算符:$stdDevPop

MongoDB聚合运算符&#xff1a;$stdDevPop 文章目录 MongoDB聚合运算符&#xff1a;$stdDevPop语法使用非数值类型的值单个值数组操作数窗口值 举例应用于$group阶段在$project阶段使用在$setWindowFields阶段使用 $stdDevPop聚合运算符用来计算输入值的总体标准差。如果确认数…