C语言趣味代码(五)

news2024/11/23 20:26:12

我想以此篇结束关于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.coloradmin.cn/o/1647978.html

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

相关文章

HTTP 多个版本

了解一下各个版本的HTTP。 上个世纪90年代初期&#xff0c;蒂姆伯纳斯-李&#xff08;Tim Berners-Lee&#xff09;及其 CERN的团队共同努力&#xff0c;制定了互联网的基础&#xff0c;定义了互联网的四个构建模块&#xff1a; 超文本文档格式&#xff08;HTML&#xff09; …

关于MS-DOS时代的回忆

目录 一、MS-DOS是什么&#xff1f; 二、MS-DOS的主要功能有哪些&#xff1f; 三、MS-DOS的怎么运行的&#xff1f; 四、微软开源MS-DOS源代码 五、高手与漂亮女同学 一、MS-DOS是什么&#xff1f; MS-DOS&#xff08;Microsoft Disk Operating System&#xff09;是微软公…

成功案例(IF=7.3)| 转录组+蛋白质组+代谢组联合分析分析揭示胰腺癌中TAM2相关的糖酵解和丙酮酸代谢重构

研究背景 肿瘤的进展和发展需要癌细胞的代谢重编程&#xff0c;癌细胞能量代谢模式的改变可以满足快速增殖和适应肿瘤微环境的需要。肿瘤微环境&#xff08;TME&#xff09;中的代谢状态受到多种因素的影响&#xff0c;包括血管生成、与其他细胞的相互作用和系统代谢。代谢异质…

桥接模式类图与代码

欲开发一个绘图软件&#xff0c;要求使用不同的绘图程序绘制不同的图形。以绘制直线和圆形为例&#xff0c;对应的绘图程序如表 7.7 所示。 根据绘图软件的扩展性要求&#xff0c;该绘图软件将不断扩充新的图形和新的绘图程序。为了避免出现类爆炸的情况&#xff0c;现采用桥接…

[Docker]容器的网络类型以及云计算

目录 知识梗概 1、常用命令2 2、容器的网络类型 3、云计算 4、云计算服务的几种主要模式 知识梗概 1、常用命令2 上一篇已经学了一些常用的命令&#xff0c;这里补充两个&#xff1a; 导出镜像文件&#xff1a;[rootdocker ~]# docker save -o nginx.tar nginx:laster 导…

基于SSM的农产品销售管理系统

文章目录 项目介绍一、项目功能介绍二、部分页面展示三、部分源码四、底部获取全部源码&#xff08;9.9&#xffe5;带走&#xff09; 项目介绍 农产品销售管理系统 一、项目功能介绍 一、介绍 系统分为两个角色 用户功能&#xff1a;登陆&#xff0c;注册&#xff0c;商品分…

实操专区-第11周-课堂练习专区-图的标记线和标记点

下载安装ECharts&#xff0c;完成如下样式图形。 代码和截图上传 完成 3.1.3.5 图的标记线和标记点 中的任务点 在一些折线图或柱状图当中&#xff0c;可以经常看到图中对最高值和最低值进行了标记。 在ECharts中&#xff0c;标记点&#xff08;markPoint&#xff09;常用于表示…

深入解析C#中的async和await关键字

文章目录 一、异步编程的基本概念及其在C#中的实现二、async关键字的定义及其用法三、await关键字的定义及其用法示例代码&#xff1a;使用async和await编写一个简单的异步程序 四、async和await的优点注意事项 五、C#下async和await中常见问题汇总1. 异步方法中的await调用2. …

森林消防泵:操作、购买攻略!/恒峰智慧科技

随着气候变化和人为活动的影响&#xff0c;森林火灾频繁发生&#xff0c;对生态环境和人类安全构成严重威胁。森林消防泵作为森林火灾扑救的重要设备&#xff0c;其性能和操作便捷性直接关系到灭火效果。本文将为您详细介绍森林消防泵的操作指南和购买攻略&#xff0c;助您更好…

【网站项目】戒烟网站

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【林业资质申报指南】申报林业工程调查规划设计丙级申报材料

【林业资质申报指南】申报林业工程调查规划设计丙级申报材料 申报林业工程调查规划设计丙级申报材料需要包括以下内容&#xff1a; 一、申报单位基本情况 申报单位应提供详细的单位介绍&#xff0c;包括单位名称、注册地址、法定代表人、注册资本、成立时间、经营范围等基本情况…

智慧校园的优势

数字化校园的建造给传统校园带来了生机与生机&#xff0c;数字化校园的每项设备都给学生带来了很好的体验。如不久前的开学季&#xff0c;许多校园运用校园一卡通体系&#xff0c;处理了往日人山人海的校园迎新现象&#xff0c;取而代之的是安静、有序的重生报到场景&#xff0…

Low Poly Animated Prehistoric Animals

该资源包与全球最优秀的古生物学家携手打造,以精确的形态和动画让史前动物栩栩如生。高质量上装束的低多边形动物,带有动画、惊艳的演示场景和漫游脚本:—内容— - 漫游脚本(V.4.5)可以将活的动物拖放到场景中 - 上装束的动物 - 优美的演示场景 - 支持 Mecanim - 20 种动物…

张大哥笔记:自媒体人10种赚钱方法

很多人都在做自媒体&#xff0c;比如平台广告分成、广告收入、公关宣传、品牌植入、演讲、会员制、出书、线下活动。那么本文介绍了自媒体人10种赚钱方法&#xff0c;供大家参考&#xff1a; 1、打造个人IP 什么是个人IP&#xff1f;在百度百科上是这样解释的&#xff1a;指个…

学术咸鱼入门指南(2)

巧用思维导图阅读文献 化整为零&#xff1a;读文献&#xff0c;从拆分文章的结构开始 大家在初步接触自己学科的论文时&#xff0c;要了解清楚基本的范式&#xff0c;日后读起来就比较顺了。 科研论文的第一部分&#xff0c;是文章的标题&#xff0c;摘要和关键词&#xff0…

机器学习之基于Python多种混合模型的糖尿病预测

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 糖尿病是一种慢性代谢性疾病&#xff0c;其发病率在全球范围内逐年上升&#xff0c;已成为影响人类健…

第11篇:创建Nios II工程之控制多个七段数码管

Q&#xff1a;DE2-115开发板上有8个七段数码管&#xff0c;如何用PIO IP并设计Nios II工程控制呢&#xff1f; A&#xff1a;基本思路&#xff1a;DE2-115上有8个7位七段数码管&#xff0c;而一个PIO最多可配置为32位&#xff0c;如此就可以添加2个PIO都配置为28位output。 Ni…

数据结构:环形链表的实战指南

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;http://t.csdnimg.cn/oHJAK&#xff08;数据结构与算法&#xff09; 小新的主页&#xff1a;编程版小新-CSDN博客 …

Jackson系统开发方法

1、Jackson分析方法是面向数据流的分析方法。这一方法从目标系统的输入、输出数据结构入手&#xff0c;导出程序框架结构&#xff0c;再补充其它细节&#xff0c;就可得到完整的程序结构图。 2、应用场景&#xff1a;这一方法对输入、输出数据结构明确的中小型系统特别有效&am…

人工智能实验:人脸检测

一、实现目的&#xff1a; 了解人脸检测的主要方法&#xff1b;了解 detectMultiScale 函数的功能及用法&#xff1b;掌握使用 OpenCV 提供的分类器和检测器进行人脸检测的方法。 二、实验设备&#xff1a; 计算机一台&#xff1b;视觉实验软件环境及资源一套&#xff08;vi…