if(ar[i]>ar[j])
{tmp=ar[i];ar[i]=ar[j];ar[j]=tmp;
}
/*for(i=0;i<11;i++)
printf("%d",ar[i]);*///此处可以打印出data中的成绩排名情况。
chuansong(ar);
}
duqu(n1)
{inti,paixu[11];
FILE*fp;
paixu[10]=n1;
if((fp=fopen("d:
\\data.txt","r+"))==NULL)
{printf("Cannotopenfile\n");
exit(0);}
while(!
feof(fp))
{for(i=0;i<10;i++)
fscanf(fp,"%d",&paixu[i]);
}
printf("\n");
fclose(fp);
sort(paixu,11);
}
voidmain()
{inti,j,n=0,m=0;
intsuiji[5];
intcaice[5];
intk[3];
srand((int)time(NULL));//定义rand的随机种子,如果不定义,rand默认种子值是1。
for(i=0;i<5;i++)//每次运行时刻产生不同的随机数列。
suiji[i]=rand()%10;
do
{
k[0]=0;k[1]=0;k[2]=0;
printf("Pleaseenteryour5guessnumbers:
\n");
for(i=0;i<5;i++)
scanf("%d",&caice[i]);
for(i=0;i<5;i++)
{if(suiji[i]==caice[i])
k[0]++;
}
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{if(caice[j]==suiji[i])
{k[2]++;
break;}
}
}
k[1]=(k[2]-k[0]);
printf("Theresultis:
\n")
printf("%dY%dN\n",k[0],k[1]);
printf("Therealresultis:
\n");
for(i=0;i<5;i++)
printf("%d\n",suiji[i]);//此处用于打印电脑产生的随机数的真实值。
n++;
m++;
}while(m<9&&(k[0]!
=5));
if(m<9&&(k[0]=5))
{printf("Youarewin\n");
duqu(n);
}
elseprintf("Thegameisover");
}
五、结果分析
(1)、先调试主函数,主函数主要功能是完成电脑产生的随机数与用户输入的5个数进行比较,并给出结果,同时会调用子函数,调试主函数时,先把duqu()子函数屏蔽掉,仅看输出的n值来判定主函数的正误,从而确保主函数是正确的,即如果用户输入超过9次,屏幕显示“Thegameisover”n值大于9,如果用户在9次机会内猜对的话,输出的n值小于9。
(2)、编写duqu()函数,duqu()的形参值是main()函数传递过来的n值,主要功能读取d盘下的data文档中的十个数,定义大小为11的数组来存放读取的10个数和n的值,在编写duqu()函数时,最好单独编写,至于n的值,先可当成已知值给予,然后调试,看数组中的数是否正确,若不正确,则继续调试,直至正确为止。
(3)、编写sort()函数,其编法采用冒泡法对数组中的11个数进行排序,各位同学对此已经很熟悉,在此不作多讲。
(4)、编写chuansong()函数,此函数通俗点说可以看成是duqu()函数的逆过程,即把排序好的11个数前10位送到data文档中保存起来。
(5)、在确保以上四个模块正确的前提下,把这四个模块“缝合”到一起,并调试观察结果。
(6)、例如某用户在9次内没有猜对其5个数的过程如下:
例如用户在第二次就猜对了
六、调试过程中的问题
1、在主函数中首先遇到的问题是产生随机数问题,rand(),srand()的使用,我们先运行两个程序:
(1)#include
#include
main()
{
inti,j;
for(i=0;i<10;i++)
{
j=rand()%10;
printf("%d",j);
}
}
第一次运行:
7524081852
第二次运行:
7524081852
我们会发现两次运行的结果会一样,其实是每次程序运行的结果都会一样。
(2)#include
#include
#include
main()
{
inti,j;
srand((int)time(NULL));
for(i=0;i<10;i++)
{
j=rand()%10;
printf("%d",j);
}
}
第一次运行:
1999928639
第二次运行:
3518283146
函数说明:
因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX间。
在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。
rand()产生的是假随机数字,每次执行时是相同的。
若要不同,以不同的值来初始化它.初始化的函数就是srand()。
我们知道rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种了,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是voidsrand(inta)功能是初始化随机产生器既rand()函数的初始值,即使把种子的值改成a;从这你可以看到通过sand()函数,我们是可以产生可以预见的随机序列,
那我们如何才能产生不可预见的随机序列呢?
我们可能常常需要这样的随机序列,是吧。
利用srand((unsign)(time(NULL))是一种方法,因为每一次运行程序的时间是不同的,对了,你知道time()函数的功能是返回从1970/01/01到现在的秒数的吧,可能这个起始时间不正确,用户可以自己查一下对不对吧,C还提供了另一个更方便的函数,randomize()
原形是voidrandomize(),功能是用来始初rand()的种子的初始值,而且该值是不确定的,它相当于srand((unsign)(time(NULL))不过应注意的是randomize()的功能要通过time来实现所以在调用它时头文件要包含time.h罢了。
七、软件设计总结
首先说明本次实验我选择的是“五位数猜谜游戏”这道题,有人说这道题比较容易,老师打分的时候起点会低,还是不选的好,但是最终我还是选择了这道所谓容易的题目,理由是:
第一,题目简单容易掌控,更会让自己去动脑筋,以积极的心态去写程序,怎样去完美一个程序,而不是抱着一颗以尽早完成任务的心态去完成任务,网上拷,背地抄,以老师的评分为最终宗旨;如果那样我个人觉得倒不如选择一道难度适合自己,让自己稍微轻松的题目,你有没有付出,有没有努力,老师也是从学生时代走过来的,老师会心中有数。
第二,也许是最主要的理由吧,当我看到这道题的时候,给我的第一感觉就是很多以前学过的知识现在已经似懂非懂了,还有的知识点就是当时老师提了一下,并没有着重去讲解,比如“文件处理”一个章节,在此情况下,自己正好理一下以前的一些基础知识,同时也学习一下“文件处理”一章,以课本为基础,学过的知识为基础,我想自己是可以胜任这道题的,事实也证明了这一点,程序是我自己通过思考一条一条编出来的,调试也是我自己一步一步调过来的,别人说这题简单,我不介意,正确的结果出现在我的眼前,我已经很满足了。
至于编程过程中的一些心得,这必须要提到的,最让我自己感到满足的有两点:
(1)、就是rand()函数的应用,不说假话,rand()函数的一些知识点是我上网查的,在函数的说明中有一部分是引用别人的,但请放心,程序依然是我自己的了。
(2)、是“*Y*N”中N的确定,我个人认为这也是整个程序的一大亮点,刚开始的时候想了3种方法,但最后都被我否定了,并不是出不来结果,而是程序编的比较长、烦,最后通过使用“break”的办法,让程序编的十分简洁,这可是我好不容易才想到的,呵呵,rand()函数前面已经详细介绍过了,在此不作过多讨论,下面就N的确定的函数作一下阐述:
for(i=0;i<5;i++)
for(j=0;j<5;j++)
{if(caice[j]==suiji[i])
{k[2]++;
break;}
}
k[1]=(k[2]-k[0]);
引用两个for循环“随机数”为比较对象,用户猜测的5个数为被比较对象,首先拿随机数第一个数与用户猜测数逐一比较,只有比较到当两个数相同时k[2]++,并且break跳出内层的for循环,继续拿“随机数”的第二个数与猜测数逐一比较,同样遇到两个数相同的时候k[2]才自加加,并且break跳出内层循环,继续外层的循环,这样算的k[2]再减去位置正确数字也正确的个数,就是位置不正确但数字正确的数字个数了。
还有最重要的一点用户必须要知道的,在本程序运行前必须要把此文件夹中名为“data”的文档拷到d盘中,此文档是记录用户猜测随机数的次数(即成绩),初次使用时,文档中的内容已经被初始化为“10101010101010101010”,如果不把此文档考到d盘中或者内部没有数等,程序都会报错!
最后还是要声明一下本程序全部为本人自己所写,真金不怕火炼,同时也希望老师能给予批评与建议,学生我会由衷感激。