c语言链表问题

yaosanfeng 2012-12-26 11:42:01

#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);
}
求高人指点,这个程序运行起来没问题,就是链表出了小错误,查看历史答题记录时,只能查看下一个记录,而查看上一个记录时还是停留在此记录上,求大侠修改指点.
...全文
273 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
没花鹿 2012-12-28
  • 打赏
  • 举报
回复
老远跑这为的是看老赵。。。和c#版的 caozhy、sp1234性格一样
赵4老师 2012-12-28
  • 打赏
  • 举报
回复
在电脑上运行程序有意思吗?每次都让CPU执行汇编指令!
赵4老师 2012-12-28
  • 打赏
  • 举报
回复
引用 4 楼 hustwbno1 的回复:
引用 3 楼 zhao4zhong1 的回复:内存地址→指针→链表。 VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停…… 有意思么 没(应为每)次都是回复这个
捕鱼有意思吗?每次都用网!
yaosanfeng 2012-12-27
  • 打赏
  • 举报
回复
大侠,谢了。我明白了,感谢你
yaosanfeng 2012-12-27
  • 打赏
  • 举报
回复
//****************练习模式**************************************************************************************************** void practice()//连续出题,不计分,直至用户回答结束 { void viewHistory(SCORE*);//函数声明 void freeList(SCORE*);//函数声明 .... for(;;)//链表 { u=(SCORE*)malloc(sizeof(SCORE));//申请连续空间(动态变量) u->next=NULL;//链表的末尾为空 if(head==NULL) { head=v=u; u->pre=NULL; } else { u->pre=v; v=v->next=u; //u->pre=v; //这一行应放到上面一行}//u v还未給值 这句话我是放在前一句的上面啊,大侠,你就好人做到底吧,说清楚,谢了,呵呵
hustwbno1 2012-12-26
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
内存地址→指针→链表。 VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Bor……
有意思么 没次都是回复这个
赵4老师 2012-12-26
  • 打赏
  • 举报
回复
内存地址→指针→链表。 VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单! 指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。” 这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑! 这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!! 提醒: “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、……
prajna 2012-12-26
  • 打赏
  • 举报
回复
见下面红色字体 //****************练习模式**************************************************************************************************** void practice()//连续出题,不计分,直至用户回答结束 { void viewHistory(SCORE*);//函数声明 void freeList(SCORE*);//函数声明 .... for(;;)//链表 { u=(SCORE*)malloc(sizeof(SCORE));//申请连续空间(动态变量) u->next=NULL;//链表的末尾为空 if(head==NULL) { head=v=u; u->pre=NULL; } else { u->pre=v; v=v->next=u; //u->pre=v; //这一行应放到上面一行 }//u v还未給值
q422013 2012-12-26
  • 打赏
  • 举报
回复
没有释放空间?

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧