c语言链表问题
#include<stdio.h>//头文件
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<math.h>
typedef struct score //存储计分信息的结构
{
int op1; //第1个整数
int op2; //第2个整数
char opp; //运算符
int right; //正确答案
int answer; //用户的解答
struct score *next; //指向下一结构
struct score *pre; //指向上一结构
}SCORE;// 类型定义
void practice(void); // 练习函数
void test(void); // 测试函数
void aSample(SCORE *,int);//抽取(链表)
void waitTime(long n) //等待时间,从0+1一直加到90000000,就是浪费是间,可以去掉
{
for(long now=0;now<n;now++);
}
//***************主函数******************
void main()//主函数
{
long now; //定义长整型now,用来保存随机生成的数
printf("\n\n\n\t\t\t欢迎使用小霸王学习机\n");//输出3次换行和3次制表(每个就占7列)然后输出欢迎使用小霸王学习机
waitTime(90000000);//调用waitTime函数,把90000000带入waitTime函数的形参n
srand(time(&now)%53);//***这是一个C的库函数,用来调用DOS下的命令或外部程序。system("cls")的意思是调用DOS下的清屏命令“cls”。
//设置随机函数的起动数值
while(1) //里面的值是1就是永远成立,是无限循环
{
int choice;
system("cls");//控制室监听;屏幕清除的系统命令!
printf("\n\n\n");//输出3次换行
printf("\t\t选择练习模式请按1\n");
printf("\t\t选择测验模式请按2\n");
printf("\t\t\t\t退出请按键Esc\n");// 输入Esc结束
while(1)//无限循环
{
choice=getch();//输入一个字符,以便下面的语句进行判断
if(choice==27)return;//"Esc"的ASII码是27
if(choice==49)break;//"1"的ASCII码是49
if(choice==50)break;//"2"的ASCII码是50(这个地方貌似用到位域)
}
if(choice==49)practice();// 选择1就意味着实战练习(调用)
else if(choice==50)test(); // 选择2则测试(调用)
}
}
//************以下为子函数部分*************
//****************查看答题历史*************************************************************************************************
void viewHistory(SCORE *t)//考虑是否查看历史记录
{
int i,choice;
do
{
printf("\n\t\t你是否想检查本次大体历史?是(Y)/否(N):");
choice=getche();///******************************************//c语言里相关的有三个
//getch() 从控制台读取一个字符,但不显示在屏幕上
//getche() 从控制台读取一个字符并回显
printf("\n\n");
}while(choice!='y'&&choice!='n'&&choice!='Y'&&choice!='N');
if(choice=='n'||choice=='N'||t==NULL)return;
system("cls"); // 清除先前的!!!
i=1;//把i初始化为1
while(1)
{
printf("第%d题:\t%d%c%d=?\n",i,t->op1,t->opp,t->op2);// 后面会给定opp与op2
printf("\t\t你的回答:%d\t\t正确答案:%d\n",t->answer,t->right);
printf("\t\t你答%s了!\n",t->answer==t->right?"对":"错");//判断你答的是否正确
if(t->next)
printf("pgDn");
if(t->pre)
printf("pgUp");
printf("Esc\n");//查看的三个操作
while(1)
{
choice=getch();
if(choice==27)//esc
return;//over
if(choice==224)
{
choice=getch();
if(choice==73&&t->pre)//up
{
t=t->pre;i--;
break;
}
else if(choice==81&&t->next)
{
t=t->next;i++;
break;
}
}
}
}
}
//*********************************************************
void freeList(SCORE *h)//set free,make it empty!!
{
SCORE *p;
while(h)
{
p=h;
h=h->next;
free(p);
}
}
//****************练习模式****************************************************************************************************
void practice()//连续出题,不计分,直至用户回答结束
{
void viewHistory(SCORE*);//函数声明
void freeList(SCORE*);//函数声明
SCORE *u,*v,*head;// 指针定义后会来引用
int range;//范围
int choice;//选择哪种模式
system("cls");// 清除运算过后
printf("\n\n\n\t进入练习模式,你将连续作答,不计分,想退出时输入Esc\n");//ESC 先前定义好了,功能已经确定,可以用了!!
printf("\n\n\n\t\t\t输入计算范围0~");
while(1)
{
scanf("%d",&range);// 接着上面的!
if(range>=2)break;
system("cls");//一个数只会运用一次就清除
printf("\n\n\n\t\t\t范围不能为0--%d,请输入一个大于1的正数\n",range);//此时range不为结构变量而是成员变量!
}
system("cls");//清除此次输入,以不影响下次循环运用!!
head=NULL;//指针滞空!
for(;;)//链表
{
u=(SCORE*)malloc(sizeof(SCORE));//申请连续空间(动态变量)
u->next=NULL;//链表的末尾为空
if(head==NULL)
{
head=v=u;
u->pre=NULL;
}
else
{
v=v->next=u;
u->pre=v;
}//u v还未給值
aSample(u,range);//例子
if(u->answer==u->right)
{
printf("\t\t\t正确!\n");
}
else
{
printf("\t\t\t错了!\n");
printf("\t\t\t正确的答案是:%d\n",u->right);//会给出正确答案!!!
}
printf("\n\n\t\t\t任意键继续\n");//这里是如何定义的啊?
printf("\t\t\t返回主菜单请按键Esc\n");
choice=getch();
system("cls");// 清除此次操作!
if(choice==27)break;//ESC
}
viewHistory(head); //完成后会有提示,是否查看历史的(调用)
freeList(head); //clean up清除
}
//*********************************************测试模式*********************************************************(与上有类似!!!!)
void test(void)
{
SCORE *u,*v,*head;
long range,num;
int i,t,err;
system ("cls");
printf("\n\n\n\t\t进入测试模式,你的回答将计分。\n");
printf("\n\n\n\t\t\t输入计算范围0 ~");
while(1) //******解题范围
{
scanf("%d",&range);
if(range>=2)break;
system("cls"); //清屏
printf("\n\n\n\t\t\t范围不能为0--%d,请输入一个大于1的正数\n",range);
}
printf("\n\t\t\t输入解题的道数");
while(1)//*****解题道数
{
scanf("%d*%c",&num);
if(num>=2) break;
system("cls");
printf("\n\n\t\t解题道数不能为0 ~ %d,请输入一个大于1的正数\n",num);
}
system("cls");
head=NULL;
for(i=0;i<num;i++)
{
u=(SCORE*)malloc(sizeof(SCORE));//回应上部分的u v定义!
u->next=NULL;
if(head==NULL)
{
head=v=u;
u->pre=NULL;
}
else
{
u->pre=v;
v=v->next=u;
}
aSample(u,range);
}
err=0;//***错误题数赋初值0(back ASCII)
system ("cls");// 罗嗦的清除!!
printf("\t\t\t测验完毕,结果如下:\n");
for(t=1,u=head;u!=NULL;u=u->next,t++)
{
if(u->answer!=u->right) //判断错误,并给出正解
{ err++; //***错误题数自增
printf("\t\t\t第%d题错误,正确的答案是:%d\n",t,u->right);
printf("\t\t\t\t%d%c%d=%d\n\n",u->op1,u->opp,u->op2,u->right);//还没给出opp,op1,op2!
waitTime(200000000);
}
}
printf("\n\t\t得%d分.\n",(num-err)*100/num);//以百分制给分(每题多少分)
printf("\t\t按任意键继续");
getch();
system ("cls");
viewHistory(head);
freeList(head);//类上
}
//**********************随机生成运算式************************************************************************(较重要部分)
void aSample(SCORE * u,int range)//opp出现!
{
int opp0,t;
opp0=rand()%4; //随机产生运算符
if(opp0==0)
{
u->opp='+';
u->op1=rand()%(range-1)+1;//随机产生整数
u->op2=rand()%(range-1)+1;//随机产生整数
if(u->op1+u->op2>range)
u->op2=range-u->op1;
u->right=u->op1+u->op2;
}
else if(opp0==1)
{
u->opp='-';
//随机产生整数
u->op1=rand()%range;//随机产生0—range的整数
u->op2=rand()%range;//随机产生0—range的整数
if(u->op1<u->op2)
{
int temp=u->op1;
u->op1=u->op2;
u->op2=temp;
}
u->right=u->op1-u->op2;
}
else if(opp0==2)
{
u->opp='*';
//随机产生整数
u->op1=rand()%range;
u->op2=rand()%range;
if(u->op1*u->op2>range)
u->op2=range/u->op1;
u->right=u->op1*u->op2;
}
else if(opp0==3)
{
u->opp='/';
u->op1=rand()%(range-1)+1;//随机产生整数
u->op2=rand()%(range-1)+1;//随机产生整数
if(u->op2==0||(u->op1)%(u->op2)!=0)//当被除数小于除数(或除数为0)时
{
t=(int)sqrt(range);//把根号range的整数值赋给t
if(t<2)t=2;
u->right=rand()%(t-1);//答案为1或0
u->op2=rand()%(t-1)+1;
u->op1=(u->right)*(u->op2);
}
else
u->right=u->op1/u->op2;
}
printf("\n\n\n\t\t\t%d %c %d=",u->op1,u->opp,u->op2);
scanf("%d%*c",&u->answer);
}
求高人指点,这个程序运行起来没问题,就是链表出了小错误,查看历史答题记录时,只能查看下一个记录,而查看上一个记录时还是停留在此记录上,求大侠修改指点.