《编游戏c语言程序设计案例》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
编游戏C语言程序设计案例精编.txt让人想念而死,是谋杀的至高境界,就连法医也鉴定不出死因。。。。。。C语言编游戏案例精编案例ー贪吃蛇游戏SdefineN200^include
1/・图形驱动・/voidInit(void)(intgd=DETECT,gm;initgraph(&gd,&grn,"c:;cleardeviceO;)/・开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙・/voidDrawK(void)(Asetbkcolor(LIGHTGREEN):*/setcolor(11);setlinestyle(SOLID„LINE,0,THICKJHDTH);/・设置线型・/for(i=50;i<=600;i+=10)/・画围墙・/{rectangle(i,40,i+10,49);/・上边・/rectangle(i,451,i+10,460);/・下边・/}for(i=40;iく=450;i+=10){rectangle(50,i,59,i+10);/・左边・/rectangle(601,i,610,i+10);/・右边・/})/・玩游戏具体过程・/voidGamePlay(void)(randomize()ノ・随机数发生器・/food.yes=l;/*l表示需要出现新食物,0表示已经存在食物・/snake.life=0;/・活着・/snake,directional;/・方向往右・/snake.x[0]=100;snake.y[0]=100;/・蛇头・/snake.x[l]=110;snake.y[l]=100;snake.node=2ノ・节数・/PrScoreO;/・输出得分・/while(1)/・可以重复玩游戏,压ESC键结束・/(while(!kbhit())/*在没有按键的情况下,蛇自己移动身体・/(if(food.yes==l)/*需要出现新食物・/(food.x-rand()%400+60;food,y=rand()%350+60;while(food.x%10!=0)/・食物随机出现后必须让食物能够在整格礼这样オ可以让蛇吃到*/food.x++;while(food.y%10!=0)food.y++;food.yes=0;/・画面ヒ有食物了・/
2}if(food.yes=0)/・画面上有食物了就要显示・/{setcolor(GREEN);rectangle(food,x,food,y,food,x+10,food,y-10);)for(i=snake.node-1;i>0;i-)/・蛇的每个环节往前移动,也就是贪吃蛇的关键算法・/(snake.x[i]=snake.x[i-l];snake,y[i]=snake.y[i-1];)/*1,2,3,4表示右,左,±,下四个方向,通过这个判断来移动蛇头・/switch(snake,direction){case1:snake,x[0]+=10;break;case2:snake,x[0]-=10;break;case3:snake.y[0]-=10;break;case4:snake,y[0]+=10;break;}for(i=3;iくsnake.node;i++)/・从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来・/(if(snake.x[i]==snake.x[0]&&snake.y[i]=snake.y[0]){Game0ver();/・显示失败・/snake.life=l;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake,y[〇]>455)/・蛇是否撞到墙壁・/(GameOverO;/・本次游戏结束・/snake.life=l;/・蛇死・/)if(snake.life=l)/・以上两种判断以后,如果蛇死就跳出内循环,.重新开始・/break;if(snake.x[0]==food.x&ftsnake.y[0]=food.y)/・吃到食物以后・/setcolor(0);/・把画面上的食物东西去掉・/rectangle(food,x,food,y,food,x+10,food,y-10);
3snake,x[snake,node]=-20;snake,y[snake,node]=-20;/・新的ー节先放在看不见的位置,下次循环就取前ー节的位置・/snake.node++;/・蛇的身体长ー节・/food.yes=l;/・画面上需要出现新的食物・/score+=10;PrScore();/・输出新得分・/)setcolor(4);/・画出蛇・/for(i=0;i 4settextstyle(0,0,4);outtextxy(200,200,"GAMEOVER");getchO;/・输出成绩・/voidPrScore(void)(charstr[10];setfillstyle(SOLIDFILL,YELLOW);bar(50,15,220,35);setcolor(6);settextstyle(0,0,2);sprintf(str,"score:%d^,score);outtextxy(55,20,str);}/・图形结束・/voidClose(void)|getch();closegraph();案例二计算器#include 5intmain(){initialize。;/*设置系统进入图形模式・/computer();/・运行计算器・/closegraph();/*系统关闭图形模式返回文本模式・/return(0);/・结束程序・/}/・设置系统进入图形模式・/voidinitialize(void)(intxasp,yasp;/・用于读x和y方向纵横比・/GraphDriver=DETECT;/・自动检测显示器・/initgraph(SGraphDriver,&GraphMode,);/・初始化图形系统・/ErrorCode=graphresult();/・读初始化结果・/if(ErrorCode!=grOk)/・如果初始化时出现错误・/(printf("GraphicsSystemError:%s 6”,grapherrormsg(ErrorCode));/・显示错误代码・/exit(1);/・退出・/}getpalette(ftpalette);/・读面板信息・/MaxColors=getmaxcolor()+1;/・读取颜色的最大值・/MaxX=getmaxx();/・读屏幕尺寸・/MaxY=getmaxyO;/・读屏幕尺寸・/getaspectratio(&xasp,&yasp);/・拷贝纵横比到变量中・/AspectRatio=(double)xasp/(double)yasp;/・计算纵横比值・/)/・计算器函数*/voidcomputer(void)(structviewporttypevp;/・定义视ロ类型变量・/intcolor,height,width;intx,y,xO,yO,i,j,v,m,n,act,flag=l;floatnuml=0,num2=0,result;/・操作数和计算结果变量・/charcnum[5],str2[20]={**},c,temp[20]={**};charstrlロ=”1230.456+-789*/Qc1%”;/・定义字符串在按钮图形上显示的符号・/mwindow("Calculator");/・显示主窗口・/color=7;/*设置灰颜色值・/getviewsettings(&vp);/・读取当前窗口的大小・/width=(vp.right+l)/10;/・设置按钮宽度・/height=(vp.bottom-10)/10;/・设置按钮高度・/x=width/2;/・设置x的坐标值・/y=height/2;/・设置y的坐标值・/setfi11style(SOLIDFILL,color+3);bar(x+width*2,y,x+7*width,y+height);/・画一个二维矩形条显示运算数和结果・/setcolor(color+3);/*设置淡绿颜色边框线・/rectangle(x+width*2,y,x+7*width,y+height); 7/・画一个矩形边框线・/setcolor(RED);/・设置颜色为红色・/outtextxy(x+3*width,y+height/2,"〇.");/・输出字符串"〇."*/x=2*width-width/2;/・设置x的坐标值・/y=2*height+height/2;/・设置y的坐标值・/for(j=0;j<4;++j)/・画按钮・/(for(i=0;i<5;++i)(setfillstyle(SOLID_FILL,color);setcolor(RED);bar(x,y,x+width,y+height);/・画一个矩形条・/rectangle(x,y,x+width,y+height);sprintf(str2,"%c",strl[j*5+i]);/*将字符保存到str2中・/outtextxy(x+(width/2),y+height/2,str2);x=x+width+(width/2);/*移动列坐标・/)y+=(height/2)*3;/*移动行坐标*/x=2*width-width/2;/・复位列坐标・/}x0=2*width;y0=3*height;x=x0;y=yO;gotoxy(x,y);/・移动光标到x,y位置・/arrow();/・显示光标・/putimage(x,y,rar,XORPUT);m=0;n=0;strcpy(str2,"");/・设置str2为空串・/while((v=specialkey())!=45)/・当压下Alt+x键结束程序,否则执行下面的循环・/{while((v=specialkey0)!=ENTER)/・当压下键不是回车时・/{putimage(x,y,rar,XORPUT);/・显示光标图象・/if(v-RIGHT)/・右移箭头时新位置计算・/if(x>=x0+6*width)/・如果右移,移到尾,则移动到最左边字符位置*/(x=xO;m=0;)else(x=x+width+width/2;m++;)/・否则,右移到下ー个字符位置・/if(v=LEFT)/・左移箭头时新位置计算・/if(x<=xO)(x=x0+6*width;m=4;)/・如果移到头,再左移,则移动到最右边字符位置*/else(x=x-width-width/2;m——;}/*否则,左移到前ー个字符位置・/if(v==UP)/・上移箭头时新位置计算*/if(y<=yO){y=y0+4*height+height/2;n=3;}/・如果移到头,再上移,则移动到最下边字符位置・/else(y=y-height-height/2;n-; 8}/・否则,移到上边ー个字符位置・/if(vニニDOWN)/・下移箭头时新位置计算・/if(y>=7*height)y=yO;n=0;}/・如果移到尾,再下移,则移动到最上边字符位置*/else(y=y+height+height/2;n++;}/・否则,移到下边ー个字符位置・/putimage(x,y,rar,XOR_PUT);/・在新的位置显示光标箭头・/}c=strl[n*5+m];/*将字符保存到变量c中・/if(isdigit(c)||c='.’)/・判断是否是数字或小数点・/{if(flagニニT)/・如果标志为T,表明为负数・/(strcpy(str2,将负号连接到字符串中・/flag=l;)/・将标志值恢复为1*/sprintf(temp,c);/*将字符保存到字符串变量temp中・/strcat(str2,temp);/・将temp中的字符串连接到str2中・/setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,str2);/・显示字符串・/}if(c='+')(numl=atof(str2);/・将第一个操作数转换为浮点数・/strcpy(str2,;/・将str2清空・/act=l;/・做计算加法标志值・/setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,“〇.");/・显示字符串・/)if(cニニ‘」){if(strcmp(str2,"")==0)/*如果str2为空,说明是负号,而不是减号・/flag=T;/・设置负数标志・/else(numl=atof(str2);/・将第二个操作数转换为浮点数・/strcpy(str2,"");/・将str2清空・/act二2;/・做计算减法标志值・/setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);/・画矩形・/outtextxy(5*width,height,"〇.");/・显示字符串・/})if(c==*')( 9numl=atof(str2);/・将第二个操作数转换为浮点数・/strcpy(str2,;/・将str2清空・/act=3;/・做计算乘法标志值・/setfillstyle(SOLID_FILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,"0.*);/・显示字符串・/)if(cニニ'/')(numl二atof(str2);/*将第二个操作数转换为浮点数・/strcpy(str2,〃”);/・将str2清空・/act=4;/・做计算除法标志值・/setfillstyle(SOLIDFILL,color+3);bar(2*width+width/2,height/2,15*width/2,3*height/2);outtextxy(5*width,height,"0.*);/・显示字符串・/)if(cニニ一){numl=atof(str2);/・将第二个操作数转换为浮点数・/strcpy(str2,"");/・将str2清空・/act二5;/・做计算乘方标志值・/setfillstyle(SOLID_FILL,color+3);/・设置用淡绿色实体填充・/bar(2*width+width/2,height/2,15*width/2,3*height/2);/・画矩形・/outtextxy(5*width,height,"0.");/・显示字符串・/}if(cニニ'%')(numl二atof(str2);/・将第二个操作数转换为浮点数・/strcpy(str2,"");/・将str2清空・/act=6;/・做计算模运算乘方标志值・/setfillstyle(SOLID_FILL,color+3);/*设置用淡绿色实体填充・/bar(2*width+width/2,height/2,15*width/2,3*height/2);/*画矩形*/outtextxy(5*width,height,"〇.");/・显示字符串・/)if(c==,=')|num2=atof(str2);/・将第二个操作数转换为浮点数・/switch(act)/・根据运算符号计算・/case1:result=numl+num2;break;/・做加法*/case2:result=numl-num2;break;/・做减法・/case3:result二numl*num2;break;/*做乘法・/case4:result=numl/num2;break;/・做除法・/ 10case4:result=pow(numl,num2);break;/・做x的y次方・/case6:result=fmod(numl,num2);break;/・做模运算・/)setfillstyle(SOLID„FILL,color+3);/*设置用淡绿色实体填充*/bar(2*width+width/2,height/2,15*width/2,3*height/2);/・覆盖结果区・/sprintf(temp,^%f^,result);/*将结果保存到temp中・/outtextxy(5*\vidth,height,temp);/*显示结果・/)if(c=='c'){numl=0;/・将两个操作数复位〇,符号标志为1*/num2=0;flag=l;strcpy(str2,"");/・将str2清空・/setfillstyle(SOL!D_FILL,color+3);/・设置用淡绿色实体填充・/bar(2*width+width/2,height/2,15*width/2,3*height/2);/・覆盖结果区・/outtextxy(5*width,height,"〇,");/・显示字符串・/}if(c二'Q')exit(〇);/・如果选择了q回车,结束计算程序・/)putimage(x,y,rar,XOR_PUT);/・在退出之前消去光标箭头・/return;/*返回*/)/・窗口函数・/voidmwindow(char*header)(intheight;cleardevice();/*清除图形屏幕・/setcolor(MaxColors-1);/*设置当前颜色为白色・/setviewport(20,20,MaxX/2,MaxY/2,1);/・设置视口大小・/height=textheight("H");/・读取基本文本大小・/settextstyle(DEFAULT_FONT,HORIZ_DIR,1レ/・设置文本样式・/settextjustify(CENTER_TEXT,TOP_TEXT);/*设置字符排列方式・/outtextxy(MaxX/4,2,header);/・输出标题・/setviewport(20,20+height+4,MaxX/2+4,MaxY/2+20,1);/*设置视口大小・/drawboder();/・画边框・/voiddrawboder(void)/・画边框*/structviewporttypevp;/・定义视ロ类型变量・/setcolor(MaxColors-1);/・设置当前颜色为白色・/setlinestyle(SOLIDLINE,0,NORMWIDTH);/・设置画线方式・/getviewsettings(&vp);/・将当前视ロ信息装入vp所指的结构中・/rectangle(0,0,vp.right-vp.left,vp.bottom-vp.top);/・画矩形边框・/}/・设计鼠标图形函数・/intarrow() 11intsize;intraw[]={4,4,4,8,6,8,14,16,16,16,8,6,8,4,4,4);/・定义多边形坐标・/setfillstyle(SOLID_FILL,2);/*设置填充模式・/fillpoly(8,raw);/・画出一光标箭头・/size=imagesize(4,4,16,16);/・测试图象大小・/rar=malloc(size);/・分配内存区域・/getimage(4,4,16,16,rar);/*存放光标箭头图象・/putimage(4,4,rar,XOR_PUT);/・消去光标箭头图象・/return0;}/・按键函数・/intspecialkey(void)intkey;while(bioskey(1)-0);/・等待键盘输入・/key=bioskey(0);/・键盘输入・/key=key&Oxff?key&Oxff:key»8;/*只取特殊键的扫描值,其余为〇・/return(key);/・返回键值・/案例三黑白棋游戏^include"graphics」”/・图形系统头文件*/^defineLEFT0x4b00/・光标左键值・/#defineRIGHT0x4d00/・光标右键值・/#defineDOWN0x5000/・光标下键值・/#defineUP0x4800/・光标上键值・/#defineESC0x01lb/*ESC键值*/^defineENTEROxlcOd/・回车键值*/inta[8][8]={0},key,score1,score2;/*具体分数以及按键与存放棋子的变量・/charplayone[3],playtwo[3];/・两个人的得分转换成字符串输出・/voidplaytoplay(void);/・人人对战函数・/voidDrawQp(void);/・画棋盘函数・/voidSetPlayColor(intx);/*设置棋子第一次的颜色・/voidMoveColor(intx,inty);/・恢复原来棋盘状态・/intQpChange(intx,inty,intz);/・判断棋盘的变化・/voidDoScore(void);/・处理分数・/voidPrintScore(intn);/・输出成绩・/voidplayWin(void);/・输出胜利者信息率//*****・主函数*********/voidmain(void)(intgd=DETECT,gr;initgraph(&gd,&gr,"c:\\tc");/・初始化图形系统・/DrawQp();/・画棋盘・/playtoplayO;/・人人对战・/ 12getchO;closegraph();/*关闭图形系统・/)voidDrawQp。/・画棋盘・/{inti,j;scorel=score2=0;/・棋手ー开始得分都为0・/setbkcolor(BLUE);for(i=100;i<=420;i+=40)(line(100,i,420,i);/・画水平线・/line(i,100,i,420);/・画垂直线・/}setcolor(0);/・取消圆周围的一・圈东西・/setfillstyle(SOLID_FILL,15);/・白色实体填充模式・/fillellipse(500,200,15,15);/・在显示得分的位置画棋・/setfillstyle(SOLlD_FILL,8);/・黑色实体填充模式・/fillellipse(500,300,15,15);a[3][3]=a[4][4]=1;/・初始两个黑棋・/a[3][4]=a[4][3]=2;/*初始两个白棋・/setfillstyle(SOLlD_FlLL,WHITE);fillellipse(120+3*40,120+3*40,15,15);fillellipse(120+4*40,120+4*40,15,15);setfillstyle(SOLID_FILL,8);fillellipse(120+3*40,120+4*40,15,15);fillellipse(120+4*40,120+3*40,15,15);scorel=score2=2;/・有棋后改变分数・/DoScore();/・输出开始分数・/}voidplaytoplay()/・人人对战・/intx,y,t=l,i,j,cc=0;while(1)/・换棋手走棋・/x=120,y=80;/・每次棋子ー开始出来的坐标,x为行坐标,y为列坐标・/while(l)/*具体ー个棋手走棋的过程・/(PrintScore(l);/・输出棋手1的成绩・/PrintScore(2);/*输出棋手2的成绩・/SetPlayColor(t);/*t变量是用来判断棋手所执棋子的颜色・/fillel1ipse(x,y,15,15);key=bioskey(〇);/・接收按键・/if(key==ESC)/*跳出游戏・/break;elseif(key==ENTER)/・如果按键确定就可以跳出循环・/(if(y!=80&&a[(x-120)/40][(y-120)/40]!=1&&a[(x-120)/40][(y-120)/40]!=2)/・如果落子位置没有棋子・/{ 13if(晩2==1)/・如果是棋手1移动・/a[(x-120)/40][(y-120)/40]=l;else/*否则棋手2移动・/a[(x-120)/40][(y-120)/40]=2;if(!QpChange(x,y,t))/・落子后判断棋盘的变化・/(a[(x-120)/40][(yT20)/40]=〇;/・恢复空格状态・/cc++;/・开始统计尝试次数・/if(cc>=64-scorel-score2)/*如果尝试超过空格数则停步・/(MoveColor(x,y);fillellipse(x,y,15,15);break;)elsecontinue;/*如果按键无效・/}DoScoreO;/・分数的改变・/break;/・棋盘变化了,则轮对方走棋・/}else/・已经有棋子就继续按键・/continue;}else/*四个方向按键的判断・/if(key==LEFT&&x>120)/・左方向键・/MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x-=40;fillellipse(x,y,15,15);}elseif(keyニニRIGHT&&Xく4004&y>80)/・右方向键・/{MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);x+=40;fillellipse(x,y,15,15);)else 14if(key==UP&&y>120)/・上方向键・/(MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);y-=40;fillellipse(x,y,15,15);}elseif(keyニニD0WN&&yく400)/・下方向键・/(MoveColor(x,y);fillellipse(x,y,15,15);SetPlayColor(t);y+=40;fillellipse(x,y,15,15);if(keyニニESC)/・结束游戏*/break;if((scorel+score2)ニニ64|Iscorelニニ0|Iscore2ニニ。)/*格子已经占满或一方棋子为〇判断胜负・/(playWinO;/・输出最后结果・/break;}t二t%2+l;/*一方走后,改变棋子颜色即轮对方走・/cc=0;/・计数值恢复为0*/}/*endwhile*/voidSetPlayColor(intt)/・设置棋子颜色・/{if(t%2==l)setfillstyle(SOLID_FILL,15)ノ・白色・/elsesetfi1Istyle(SOLID_FILL,8);/・灰色・/}voidMoveColor(intx,inty)/・走了一步后恢复原来格子的状态・/(if(y〈100)/・如果是从起点出发就恢复蓝色・/setfilIstyle(SOLID_FILL,BLUE);else/・其他情况如果是1就恢复白色棋子,2恢复黑色棋子,或恢复蓝色棋盘・/ 15switch(a[(x-120)/40][(y-120)/40])(case1:setfilIstyle(SOLIDFILL,15);break:/・白色・/case2:setfi1Istyle(SOLIDFILL,8);break;/・黑色・/default:setfilIstyle(SOLID_FILL,BLUE):/・蓝色・/intQpChange(intx,inty,intt)/・判断棋盘的变化・/(inti,j,k,kk,ii,jj,yes:yes=0;i=(xT20)/40:/・计算数组元素的行下标・/j=(y-120)/40;/・计算数组元素的列下标・/SetPlayColor(t):/・设置棋子变化的颜色・//・开始往8个方向判断变化・/if(jく6)/・往右边・/(for(k=j+l:k<8;k++)if(a[i][k]==a[i][j]I[a[i][k]==0)/・遇到自己的棋子或空格结束・/break:if(a[i][k]!=0&&k<8)(for(kk=j+l:kk 16yes=l;if(iく6)/*判断下边・/{for(k=i+l;k<8;k++)if(a[k][j]==a[i][j]||!a[k][j])break;if(a[k][j]!=0&&k<8)(for(kk=i+l;kk 17(a[ii][jj]=a[i][j];fillellipse(120+ii*40,120+jj*40,15,15);)if(ii!=i-l)yes=l;)}if(i〈6&&j>l)/・左下・/(for(k=i+l,kk=j-l;k<8&&kk>=0;k++,kk一)if(a[k][kk]==a[i][j]||!a[k][kk])break;if(a[k][kk]!=0&&k<8&&kk>=0)(for(ii=i+l,jj=j-l;ii 18if(i<6&&j<6)/・右ード・/(for(k=i+l,kk=j+l;kkく8&&kkく8;k++,kk++)if(a[k][kk]=-a[i][j]||!a[k][kk])break;if(a[k][kk]!=0&&kk<8&&k<8)(for(ii-i+1,jj=j+l;ii 19)else(sprintf(playtwo,"%d”,score2);outtextxy(550,300,playtwo);)setcolor(0);}voidplayWin()/・输出最后的胜利者结果・/{settextstyle(0,0,4);setcolor(12);if(score2>scorel)/*开始判断最后的结果・/outtextxy(100,50,"blackwin!");elseif(score2 20voidNotFind(void);/・失败处理・/voidmain(void)/・主函数・/{intmap[N][N];/・迷宫数组・/charch;clrscr();printf(* 21Pleaseselecthand(l)elseauto 22");/・选择探索方式・/scanf("祝",&ch);InitO;/・初始化・/MapRand(map);/・生成迷宫・/PrMap(map);/・显示迷宫图・/if(ch==,r)PeopleFind(map);/・人工探索・/elseFindWay(map,1,1);/・系统自动从下标1,I的地方开始探索・/Result。;/・输出结果・/Close。;}voidInit(void)/・图形初始化*/(intgd=DETECT,gm;initgraph(&gd,&gm,"c:\\tc〃);}voidDrawPeople(int*x,int*y,intn)/・画人工控制图・/{/・如果将以下两句注释掉,则显示人工走过的路径,*/setfillstyle(SOLID_FILL,WHITE);/・设置白色实体填充样式・/bar(100+(*y)*15-6,50+(*x)*15-6,100+(*y)*15+6,50+(*x)*15+6);/・恢复原通路・/switch(n)/・判断x,y的变化,8个方向的变化・/{case1:(*x)—;break;/*上・/case2:(*x)—;(*y)++;break;/・右上・/case3:(*y)++;break;/・右・/case4:(*x)++;(*y)++;break;/・右下・/case5:(*x)++;break;/・下・/case6:(*x)++;(*y)—;break;/・左下・/case7:(*y)—;break;/*左*/case8:(*x)--;(*y)—;break;/・左上・/)setfillstyle(SOLIDFILL,RED);/・新位置显示探索物・/bar(100+(*y)*15-6,50+(*x)*15-6,100+(*y)*15+6,50+(*x)*15+6); 23)voidPeopleFind(int(*map)[N])/・人工手动查找・/(intx,y;charc=0;/・接收按键的变量・/x=y=l;/・人工查找的初始位置*/setcolor(11);line(500,200,550,200);outtextxy(570,197,*d*);line(500,200,450,200);outtextxy(430,197,"a");line(500,200,500,150);outtextxy(497,130,*w*);line(500,200,500,250);outtextxy(497,270,"x");line(500,200,450,150);outtextxy(445,130,"q");line(500,200,550,150);outtextxy(550,130,"e");line(500,200,450,250);outtextxy(445,270,"z");line(500,200,550,250);outtextxy(550,270,"c");/・以上是画8个方向的控制介绍・/setcolor(YELLOW);outtextxy(420,290,"Press'Enter'toend");/・压回车键结束・/setfillstyle(SOLID_FILL,RED);bar(100+y*15-6,50+x*15-6,100+y*15+6,50+x*15+6);/・入口位置显示・/、〃»1。N!=13)/・如果按下的不是回车键・/(c=getch();/*接收字符后开始各个方向的探索・/if(c==,w'&&map[x-l][y]!=1)DrawPeople(&x,&y,1);/・上・/elseif(c='e'&&map[x-l][y+1]!=1)DrawPeople(&x,&y,2);/・右上・/elseif(c==,d'&&map[x][y+1]!=1)DrawPeople(&x,&y,3);/・右・/elseif(cニニ’c'&&map[x+l][y+1]!=1)DrawPeople(&x,&y,4);/*右下*/elseif(cニニ'x'&&map[x+l][y]!=1)DrawPeople(4x,&y,5);/・下・/else 24if(c='z'&&map[x+l][y-1]!=1)DrawPeople(&x,&y,6);/・左下・/elseif(cニニ'a'&&map[x][y-1]!=1)DrawPeople(&x,&y,7);/・左・/elseif(cニニ'q'&&map[x~l][y-1]!=1)DrawPeople(&x,&y,8);/・左上・/)setfillstyle(SOLID_FILL,WHITE);/・消去红色探索物,恢复原迷宫图・/bar(100+y*15-6,50+x*15-6,100+y*15+6,50+x*15+6);if(xニニN12&&yニニN-2)/・人工控制找成功的话・/yes二1;/・如果成功标志为1*/}voidWayCopy(int(*oldmap)[N],int(*map)[N])/・拷贝迷宫数组*/(inti,j;for(i二〇;iくN;i++)for(j=0;j 25{FindWay(oldmap,i+1,j);if(yes){way[wayn][0]=i;way[wayn++][l]=j;return;})WayCopy(oldmap,map);if(oldmap[i][j+1]ニニ0&&!yes)/・判断右方是否可以走・/(FindWay(oldmap,i,j+1);if(yes)(way[wayn][0]=i;way[wayn++][l]=j;return;}}WayCopy(oldmap,map);if(oldmap[iT][j]=0&&!yes)/・判断上方是否可以走*/{FindWay(oldmap,i-l,j);if(yes)(way[wayn][0]=i;way[wayn++][1]二j;return;))WayCopy(oldmap,map);if(oldmap[iT][j+l]=O&&!yes)/・判断右上方是否可以走*/{FindWay(oldmap,i-l,j+1);if(yes)way[wayn][0]=i;way[wayn++][l]=j; 26return;})WayCopy(oldmap,map);if(oldmap[i+1][jT]=0&&!yes)/・判断左下方是否可以走*/{FindWay(oldmap,i+1,j-1);if(yes){way[wayn][0]=i;way[wayn++][l]=j;return;})WayCopy(oldmap,map);if(oldmap[i][jT]ニニ0&&!yes)/*判断左方是否可以走・/(FindWay(oldmap,i,j-1);if(yes)(way[wayn][0]=i;way[wayn++][l]=j;return;}}WayCopy(oldmap,map);if(oldmap[iT]仃ー1]=0&&W。5)/・判断左上方是否可以走*/{FindWay(oldmap,i-l,j-1);if(yes)(way[wayn][0]=i;way[wayn++][1]二j;return;))return;}voidMapRand(int(*map)[N])/・开始的随机迷宫图・/(inti,j; 27cleardeviceO;/・清屏・/randomize();/・随机数发生器・/for(i=0:i 28bar(100+(N-2)*15-6,50+(N-2)*15-6,100+(N-2)*15+6,50+(N-2)*15+6);/・在目标点标红色・/setcolor(GREEN);settextstyle(0,0,2);/*设置字体大小・/outtextxy(130,400,"Findaway!");}voidNotFind(void)/・没找到通路・/(setcolor(GREEN);settextstyle(O,0,2);/・设置字体大小・/outtextxy(130,400,*Notfindaway!*);}voidResult(void)/*结果处理*/(if(yes)/・如果找到・/FindO;else/・没找到路・/NotFind();getchO;}voidClose(void)/・图形关闭・/{closegraph();案例五扫地雷游戏#include 29intMouseExist;intMouseButton;intMouseX;intMouseY;voidInit(void);/・图形驱动・/voidMouseOn(void);/・鼠标光标显示*/voidMouseOff(void);/・鼠标光标隐藏*/voidMouseSetXY(int,int);/*设置当前位置・/intLeftPress(void);/・左键按下・/intRightPress(void);/・鼠标右键按ド*/voidMouseGetXY(void);/・得到当前位置・/voidControl(void);/・游戏开始,重新,关闭・/voidGameBegain(void);/・游戏开始画面・/voidDrawSmile(void);/・画笑脸・/voidDrawRedflag(int,int);/・显示红旗・/voidDrawEmpty(int,int,int,int);/・两种空格子的显示・/voidGameOver(void);/・游戏结束・/voidGameWin(void);/・显示胜利・/intMineStatistics(int,int);/*统计每个格子周围的雷数*/intShowWhite(int,int);/・显示无雷区的空白部分・/voidGamePlay(void);/・游戏过程・/voidClose(void);/・图形关闭・/voidmain(void)(InitO;Control();Close();)voidInit(void)/・图形开始・/(intgd二DETECT,gm;initgraph(&gd,&gm,〃c:\\tc");}voidClose(void)/・图形关闭・/(closegraph();}voidMouseOn(void)/・鼠标光标显示*/(_AX=0x01;geninterrupt(0x33);)voidMouseOff(void)/・鼠标光标隐藏・/ 30{_AX=0x02;geninterrupt(0x33);}voidMouseSetXY(intx,inty)/・设置当前位置・/(_CX=x;.DX=y;_AX=0x04;geninterrupt(0x33);)intLeftPress(void)/*鼠标左键按下・/(AX=0x03;geninterrupt(0x33);return(_BX&1);)intRightPress(void)/・鼠标右键按下・,{_AX=0x03;geninterrupt(0x33);return(_BX&2);}voidMouseGetXY(void)/・得到当前位置・/(_AX=0x03;geninterrupt(0x33);MouseX=_CX;MouseY=_DX;)voidControl(void)/・游戏开始,重新,关闭・/(intgameFLAG=l;/・游戏失败后判断是否重新开始的标志・/while(1)(if(gameFLAG)/・游戏失败后没判断出重新开始或者退出游戏的话就继续判断・/(GameBegainO;/・游戏初始画面・/GamePlay();/*具体游戏・/if(gameAGAINニニ1)/・游戏中重新开始・/(gameAGAIN二〇;continue;)) 31MouseOnO;gameFLAG=0;if(LeftPress())/・判断是否重新开始・/|MouseGetXY();if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85)(gameFLAG=l;continue;}}if(kbhit())/・判断是否按键退出・/break;}MouseOff();}voidDrawSmile(void)/・画笑脸・/(setfillstyle(SOLID一FILL,YELLOW);fillellipse(290,75,10,10);setcolor(YELLOW);setfillstyle(SOLID_FILL,BLACK);/・眼睛・/fillellipse(285,75,2,2);fillellipse(295,75,2,2):setcolor(BLACK);/・嘴巴・/bar(287,80,293,81);}voidDrawRedflag(inti,intj)/・显示红旗・/(setcolor(7);setfillstyle(SOLID_FILL,RED):bar(198+j*20,95+i*20,198+j*20+5,95+i*20+5);setcolor(BLACK);line(198+j*20,95+i*20,198+j*20,95+i*20+10);}voidDrawEmpty(inti,intj,intmode,intcolor)/・两种空格子的显示・/(setcolor(color);setfillstyle(SOLID_FILL,color);if(mode==0)/・没有单击过的大格子・/bar(200+j*20-8,100+i*20-8,200+j*20+8,100+i*20+8);elseif(mode==l)/・单击过后显示空白的小格子*/ 32bar(200+j*20-7,100+i*20-7,200+j*20+7,100+i*20+7);}voidGameBegain(void)/・游戏开始画面・/inti,j;cleardevice();if(gamePLAY!=l){MouseSetXY(290,70);/・鼠标ー开始的位置,并作为它的初始坐标・/MouseX=290;MouseY=70;)gamePLAY=l;/・卜.次按重新开始的话鼠标不重新初始化*/mineNUM=0;setfillstyle(S0LID_FILL,7);bar(190,60,390,290);for(i=0;iく10;i++)/・画格子・/for(j=0;j<10;j++)DrawEmpty(i,j,0,8);setcolor(7);DrawSmileO;/・画脸・/randomize();for(i=0;iC10;i++)/*100个格子随机赋值有没有地雷*/for(j=0;j<10;j++)(Mine[i][j].num=random(8);/・如果随机数的结果是1表示这个格子有地雷・/if(Mine[i][j].num==l)min6NUM++;/・现有雷数加1*/elseMine[i][j].num=2;Mine[i][j].flagニ〇;/・表示没红旗标志・/)sprintf(randmineNUM,mineNUM);/・显示这次总共有多少雷数・/setcolor(1);settextstyle(0,0,2);outtextxy(210,70,randmineNUM);mineNUM=100-mineNUM;/・变量取空白格数量・/MouseOn();}voidGameOver(void)/・游戏结束画面・/(inti,j;setcolor(0);for(i=0;i<10;i++)for(j=0;j<10;j++)if(Mine[i][j],nunp=l)/・显示所有的地雷・/ 33DrawEmpty(i,j,0,RED);setfillstyle(SOLID_FILL,BLACK);fillellipse(200+j*20,100+i*20,7,7);voidGameWin(void)/・显示胜利・/(setcolor(11);settextstyle(0,0,2);outtextxy(230,30,"YOUWIN!");}intMineStatistics(inti,intj)/・统计每个格子周围的雷数・/(intnNUM=0;if(iニニ0&aj=0)/・左上角格子的统计・/{if(Mine[0][1].num=l)nNUM++;if(Mine[1][0].numニニ1)nNUM++;if(Mine[l][l].num==l)nNUM++;}elseif(iニニ0&&jニニ9)/*右上角格子的统计・/(if(Mine[〇][8].numニニDnNUM++;if(Mine[l][9].numニニ1)nNUM++;if(Mine[l][8].numニニ1)nNUM++;}elseif(iニニ9&&jニニ〇)/・左下角格子的统计・/(if(Mine[8][0].numニニ1)nNUM++;if(Mine[9][1].numニニ1)nNUM++;if(Mine[8][l].num=l)nNUM++; 34elseif(i==9&&j=9)/・右下角格子的统计・/(if(Mine[9][8].num==l)nNUM++;if(Mine[8][9].num==l)nNUM++;if(Mine[8][8].num==l)nNUM++;)elseif(j=0)/・左边第一列格子的统计・/(if(Mine[i][j+1].num==l)nNUM++;if(Mine[i+1][j].num==l)nNUM++;if(Mine[i-l][j].num==l)nNUM++;if(Mine[i-1][j+1].num==l)nNUM++;if(Mine[i+1][j+1].num==l)nNUM++;)elseif(j=9)/・右边第一列格子的统计・/{if(Mine[i][j-1].num=l)nNUM++;if(Mine[i+1][j].nunr=l)nNUM++;if(Mine[i-l][j].num==l)nNUM++;if(Mine[i-1][j-1].num~l)nNUM++;if(Mine[i+1][j-1].num==l)nNUM++;}elseif(i==0)/・第一行格子的统计・/(if(Mine[i+1][j].num==l)nNUM++;if(Mine[i][j-1].num==l)nNUM++;if(Mine[i][j+1].num==l) 35nNUM++;if(Mine[i+1][j_l].num==l)nNUM++;if(Mine[i+1][j+1].num==l)nNUM-H-;elseif(i=9)/・最后一行格子的统计・/if(Mine[i-1][j].num==l)nNUM++;if(Mine[i][j-1].num==l)nNUM++;if(Mine[i][j+1].num==l)nNUM++;if(Mine[i-l][j-1].num==l)nNUM++;if(Mine[i-1][j+1].num==l)nNUM++;e1se/・普通格子的统计・/(if(Mine[i-l][j].num==l)nNUM++;if(Mine[i-1][j+1].num==l)nNUM++;if(Mine[i][j+1].num==l)nNUM++;if(Mine[i+1][j+1].num==l)nNUM++;if(Mine[i+1][j].num==l)nNUM++;if(Mine[i+1][j-1].num==l)nNUM++;if(Mine[i][j-1].num=l)nNUM++;if(Mine[i-l][j-l].num=l)nNUM++;}return(nNUM);/・把格子周围ー共有多少雷数的统计结果返回・/}intShowWhite(inti,intj)/・显示无雷区的空白部分・/if(Mine[i][j].flag==l||Mine[i][j].num=O)/*如果有红旗或该格处理过就不对该格进行任何判断・/return;mineNUM--;/・显示过数字或者空格的格子就表示多处理了一个格子,当所有格子都处理过了表示胜利・/if(Mine[i][j].roundnum-0&&Mine[i][j].num!=l)/・显示空格・/(DrawEmpty(i,j,1,7);Mine[i][j].num=0; 36)elseif(Mine[i][j].roundnum!二〇)/・输出雷数・/{DrawEmpty(i,j,0,8);sprintf(randmineNUM,"%d”,Mine[i][j].roundnum);setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);Mine[i][j].num=0;/・已经输出雷数的格子用〇表示已经用过这个格子・/return;)/*8个方向递归显示所有的空白格子・/if(i!=0&&Mine[i-l][j].num!=l)ShowWhite(i-l,j);if(i!=0&&j!=9&&Mine[i-1][j+1].num!=l)ShowWhite(i-1,j+1);if(j!=9&&Mine[i][j+1].num!=l)ShowWhite(i,j+1);if(j!=9&&i!=9&&Mine[i+l][j+1].num!=l)ShowWhite(i+1,j+1);if(i!=9&&Mine[i+l][j].num!=l)ShowWhite(i+1,j);if(i!=9&&j!=0&&Mine[i+l][j-1].num!=l)ShowWhite(i+1,j-1);if(j!=0&&Mine[i][j-1].num!=l)ShowWhite(i,j-1);if(i!=0&&j!=0&&Mine[i-l][j-1].num!=l)ShowWhite(i-1,j-1);}voidGamePlay(void)/・游戏过程・/(inti,j,Num;/*Num用来接收统计函数返回一个格子周围有多少地雷・/for(i=0;i<10;i++)for(j=0;j<10;j++)Mine[i][j].roundnum=MineStatistics(i,j);/・统计每个格子周围有多少地雷・/while(!kbhit())if(LeftPress())/・鼠标左键盘按下・/MouseGetXY():if(MouseX>280&&MouseX〈300&&MouseY>65&&MouseYC85)/*重新来・/IMouseOffO;gameAGAIN=1;break; 37)if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/・当前鼠标位置在格子范围内(j=(MouseXT90)/20;/*x坐标*/i=(MouseY-90)/20;/*y坐标・/if(Minefi][j].flag=l)/・如果格子有红旗则左键无效・/continue;if(Mine[i][j].num!=0)/*如果格子没有处理过・/(if(Mine[i][j].num==l)/・鼠标按下的格子是地番・/(MouseOff();GameOverO;/・游戏失败・/break;)else/・鼠标按下的格子不是地雷・/{MouseOff();Num=MineStatistics(i,j);if(Num==0)/・周围没地雷就用递归算法来显示空白格子・/ShowWhite(i,j);else/・按下格子周围有地雷・/(sprintf(randmineNUM,"%d",Num);/・输出当前格子周围的雷数*/setcolor(RED);outtextxy(195+j*20,95+i*20,randmineNUM);mineNUM-J)MouseOnO;Mine[i][j].num=0;/・点过的格子周围雷数的数字变为〇表示这个格子已经用过if(mineNUM<1)/・胜利了・/{GameWin();break;)if(RightPress())/・鼠标右键键盘按下・/{MouseGetXYO;if(MouseX>190&&MouseXく390&&MouseY>90&&MouseYく290)/・当前鼠标位置在格子范围内・/ 38{j=(MouseX-190)/20;/*x坐标*/i=(MouseY-90)/20;/*y坐标*/MouseOff();if(Mine[i][j].flag==0&&Mine[i][j].num!ニ0)/・本来没红旗现在显示红旗・/(DrawRedflag(i,j);Mine[i][j].flag=l;)elseif(Mine[i][j].flag=l)/・有红旗标志再按右键就红旗消失・/(DrawEmpty(i,j,0,8);Mine[i][j].flag=0;))MouseOn();sleep(l);案例六速算24#defineN20#defineCOL100^defineROW40#include"stdio.h"#include"time,h”/・系统时间函数・/^include"graphics.h〃/・图形函数*/^include"alloc,h"/・动态地址分配函数・/^include"stdlib.h"/・库函数・/#include"string,h"/・字符串函数・/^include"ctype.h"/・字符操作函数・/charp[4][13]={{'A','2','3','4,'5','6','7','8','9',‘〇','J','Q','K'},/・扑克牌,10用〇来表示・/{'A','2,'3','4','5','6','7','8,‘9',’〇','J','Q','K'},{'A','2','3','4','5','6','7','8','9','O','J','Q','K'),{'A','2','3','4','5','6','7','8','9','O','J','Q','K'});typedefstructnode 39{intdata;structnode*link;}STACK1;/・栈1*/typedefstructnode2{chardata;structnode2*link;JSTACK2;/・栈2*/voidinit(void);/・图形驱动・/voidclose(void);/・图形关闭・/voidplay(void);/・发牌的具体过程・/voidrandl(intj);/・随机发牌函数・/voidchange(char*e,char*a);/・中缀变后缀函数・/intcomputer(char*s);/・后缀表达式计算函数・/STACK1*initstackl(STACKl*top);/・栈1初始化・/STACK1*push(STACKl*top,intx);/・栈1入栈运算・/STACK1*pop(STACK1*top);/・栈1删除栈顶元素・/inttopx(STACK1*top);/・栈1读栈顶元素・/STACK1*ptop(STACKl*top,int*x);/・栈1读出栈顶元素值并删除栈顶元素・/intempty(STACK1*top);/・判栈1是否为空函数・/STACK2*initstack2(STACK2*top);/・栈2初始化・/STACK2*push2(STACK2*top,charx);/・栈2入栈运算・/STACK2*pop2(STACK2*top);/・栈2删除栈顶元素・/chartopx2(STACK2*top);/*栈2读栈顶元素・/STACK2*ptop2(STACK2*top,char*x);/・栈2读出栈顶元素值并删除栈顶元素・/intempty2(STACK2*top);/・判栈2是否为空函数・inttextl(char*s);/・显示文本・/main(){chars[N],si[N],ch;inti,result;intgdriver,gmode;clrscrO;/・清屏・/init0;/・初始化函数・/while(l)(setbkcolor(BLACK);/・设置背景颜色・/cleardevice();/・清屏・/play();/・发牌・/gotoxyd,15);/・移动光标・/printf("Note 40");printflPleaseenterexpressaccrodingtoabovefournumber'n");/*提刀く1百息・/printf(*Formatasfollows*.*(5.+7.) 41");/*提示输入字符串格式・/ 42printfl 43");scanf("%s%c”,sl,&ch);/・输入字符串压回车键・/change(si,s);/・调用change函数将中缀表达式si转换为后缀表达式s*/result=computer(s);/*计算后缀表达式的值,返回结果result*/if(result==24)/・如果结果等于24*/text1(*verygood");/*调用函数textl显示字符串“verygood"*/elsetext1("wrong!!!");/・否则函数text1显示字符串"wrong!!!"*/printf("Continue(y/n)? 44");/・提示信息,是否继续・/scanf("%c”,&ch);/*输入一字符・/if(ch==,n*I|ch==,N*)/*如果该字符等于n或N*/break;/*跳出循环,程序结束・/}/・否则,开始下ー轮循环・/close();return;/・返回・/)voidrandl(intj)/・随机发牌函数・/(intkind,num;charstr[3],n;randomize();while(1)/・循环直到有牌发・/{kind=random(4);/・花色随机数・/num二random(13);/・大小随机数・/if(p[kind][num]!=-1)/*该数未取过・/(n=p[kind][num];/・取相应位置的扑克牌数・/ptkind][num]=T;/・牌发好以后相应位置的元素置T*/break;))switch(kind)/・花式的判断・/(case0:setcolor(RED);sprintf(str,"%c",3);break;/・红桃・/case1:setcolor(BLACK);sprintf(str,"%c",3);break;/・黑桃・/case2:setcolor(RED);sprintf(str,*%c*,4);break;/・方片・/case3:setcolor(BLACK);sprintf(str,*%c*,5);break;/・草花*/settextstyle(0,0,2);outtextxy(C0L+j*100-30,R0W+100-46,str);/*显示左上角花色・/outtextxy(COL+j*100+16,R0W+100+32,str);/・显示右下角花色・/if(n!=〇')/・输出其他牌・/{settextstyle(O,0,3); 45sprintf(str,"%c”,n);outtextxy(COL+j*100-5,ROW+100-5,str);/・显示牌的大小・/)else/・输出10的时候・/(sprintf(str,"%d”,10);outtextxy(COL+j*100-6,ROW+100-5,str);voidplay(void)/求发牌的具体过程・/(intj;for(j=0;jく4;j++)(bar(C0L+j*100-35,R0W+100-50,C0L+j*100+35,ROW+1*100+50);/・画空牌・/setcolor(BLUE);rectangle(COL+j*100-32,R0W+100-48,C0L+j*100+32,R0W+100+48);/・画矩形框・/randl(j);/・随机取牌・/delay(10000);/・延时显示・/voidinit(void)/・图形驱动・/(intgd二DETECT,gm;initgraph(&gd,c:\\tc");cleardevice();)voidclose(void)/・图形关闭・/(closegraph();)voidchange(char*e,char*a)/・中缀字符串e转后缀字符串a函数・/(STACK2札op二NULL;/・定义栈顶指针・/inti,j;charw;i-0;j二。;while(e[i]!=‘、〇')/*当字符串没有结束时・/ 46if(isdigit(e[iP)/・如果字符是数字・/(do{a[j]=e[i];/・将数字原样拷贝到数组a中・/i++;/*e数组的下标加1*/j++;/*a数组的下标加1*/}while(e[i]!='.');/・直到字符为数字结束符"为止・/;j++;/・将数字结束符”.”拷贝到a数组依然保持结束标记・/)if(e[i]=='(')/・如果字符是“(”时・/top=push2(top,e[i]);/・将其压入堆栈・//・如果字符是“)”时・/(top=ptop2(top,&w);/・取出栈顶元素,并从栈顶删除该元素・/while(w!='(')/・如果字符不是“(”时反复循环・/(a[j]-w;/・将栈顶元素存入a数组・/j++;/*下标加1*/top=ptop2(top,&w);/・取出栈顶元素,并从栈顶删除该元素・/))if(e[i]=>+,I|e[i]=->)/・如果字符是加或减号时・/(if(!empty2(top))/*如栈不为空・/(w=topx2(top);while(w!='(')/・当栈顶元素不是“(”时反复循环・/(a[j]=w;j++;/・将栈顶元素存入表达式a中,a的下标加1*/top=pop2(lop);/・删除栈顶元素・/if(empty2(top))/・如果栈为空・/break;/・跳出循环・/elsew=topx2(top);/・否则读栈顶元素・/))top=push2(top,e[i]);/・将当前e的字符元素压入堆栈・/ 47)if(e[i]=='*'||e[i]=='/')"如果字符是乘或除号时・/( 48w=topx2(top);/・读栈顶元素存入w*/while(wニニ‘*’丨|wニニ'/')/・当栈顶元素是乘或除时反复循环・/(aEj]=w;j++;/・将栈顶元素存入字符串a中,a的下标加1*/top二pop2(top);/*删除栈顶元素・/if(empty2(top))/・如果栈为空・/break;/*跳出循环・/elsew=topx2(top);/・否则读栈顶元素・/top=push2(top,e[i]);/*将当前e字符元素压入堆栈・/}i++;/*e的下标加1*/}while(!empty2(top))/・当不为空时反复循环・/top=ptop2(top,&a[j++]);/・将栈顶元素存入数组a中・/a[j]='\0';/・将字符串结束标记写入最后ー个数组元素中构成字符串・/}intcomputer(char*s)/*计算函数・/(STACK1*top=NUIX;inti,k,numl,num2,result:i=0:while(s[i]!='\0')/*当字符串没有结束时作以下处理・/(if(isdigit(s[i]))/*判字符是否为数字・/(k=0;/*k初值为0・/do{k=l0*k+s[i]」〇';/・将字符连接为十进制数字・/i++;/*i加1*/}while(s[i]!='.');/・当字符不为时重复循环・/top=push(top,k);/・将生成的数字压入堆栈・/)if(s[i]='+')/・如果为‘+’号・/(top=ptop(top,&num2);/*将栈顶元素取出存入num2中・/top=ptop(top,&numl);/・将栈顶元素取出存入numl中・/result-num2+numl;/・将num!和num2相加存入result中・/top=push(top,result);/・将result压入堆栈・/)if(s[i]='-')/・如果为',号*/ 49top=ptop(top,&num2);/*将栈顶元素取出存入num2中・/top=ptop(top,&numl);/・将栈顶元素取出存入numl中・/result=numl-num2;/・将numl减去num2结果存入result中・/top=push(top,result);/・将result压入堆栈・/)if(s[i]=,*')/*如果为‘*’号・/(top=ptop(top,&num2);/*将栈顶元素取出存入num2中・/top=ptop(top,&numl);/・将栈顶元素取出存入numl中・/result=numl*num2;/・将numl与num2相乘结果存入result中・/top=push(top,result);/・将result压入堆栈・/}if(s[i]='/')/・如果为‘/'号・/(top=ptop(top,&num2);/・將栈顶元素取出存入num2中・/top=ptop(top,&numl);/・将栈顶元素取出存入numl中・/result=numl/num2;/・将numl除num2结果存入result中・top=push(top,result);/・将result压入堆栈・/}i++;/*i加1*/)top=ptop(top,&result);/*最后栈顶元素的值为计算的结果・/returnresult;/・返回结果・/)STACK1*initstackl(STACK1*top)/・初始化・/(top=NULL;/・栈顶指针置为空・/returntop;/・返回栈顶指针・/)STACK1*push(STACKl*top,intx)/・入栈函数・/(STACK1*p;/・临时指针类型为STACK1*/p=(STACK1*)malloc(sizeof(STACKD);/・申请STACK1大小的空间・/if(p==NULL)/・如果p为空・/{printf("memoryisoverflow 50!!");/・显示内存溢出・/exit(0);/・退出・/}p->data=x;/・保存值x到新空间・/p->link=top;/・新结点的后继为当前栈顶指针・/top=p;/・新的栈顶指针为新插入的结点・/returntop;/・返回栈顶指针・/STACK1*pop(STACK1*top)/・出栈*/ 51(STACK1*q;/・定义临时变量・/q=top;/・保存当前栈顶指针・/top=top->1ink;/・栈顶指针后移・/free(q);/*释放q*/returntop;/*返回栈顶指针・/)inttopx(STACKl*top)/・读栈顶元素・/(if(top=NULL)/・栈是否为空・/{printfCStackisnull 52");/・显示栈为空信息・/return0;/・返回整数〇・/)returntop->data;/・返回栈顶元素・/}STACK1*ptop(STACK1*top,int*x)/・取栈顶元素,并删除栈顶元素・/(=topx(top);/・读栈顶元素・/top=pop(top);/・删除栈顶元素・/returntop;/*返回栈顶指针・/}intempty(STACK1*top)/・判栈是否为空・/(if(topニニNULL)/・如果为空・/return1;/*返回1*/elsereturn0;/・否则返回。*/)STACK2*initstack2(STACK2*top)/・初始化・/(top二NULL;/・栈顶指针置为空・/returntop;/*返回栈顶指针*/}STACK2*push2(STACK2*top,charx)/・入栈函数・/(STACK2*p;/*临时指针类型为STACK2*/p=(STACK2*)malloc(sizeof(STACK2));/*申请STACK2大小的空间・/if(p==NULL)/・如果p为空・/(printf("memoryisoverflow'n!!”);/・显示内存溢出・/exit(0);/・退出・/ 53p->data=x;/・保存值x到新空间・/pー〉link=top;/・新结点的后继为当前栈顶指针・/top=p;/・新的栈顶指针为新插入的结点・/returntop;/・返回栈顶指针・/}STACK2*pop2(STACK2*top)/・出栈*/{STACK2*q;/*定义临时变量・/q=top;/・保存当前栈顶指针・/top=top->link;/・栈顶指针后移・/free(q);/*释放q*/returntop;/・返回栈顶指针・/}chartopx2(STACK2*top)/・读栈顶元素・/(if(top=WLL)/・栈是否为空・/{printf("Stackisnull'n");/・显示栈为空信息・/return'';/・返回空字符・/)returntop->data;/*返回栈顶元素・/}STACK2*ptop2(STACK2*top,char*x)/・取栈顶元素,并删除栈顶元素・/(*x=topx2(top);/・读栈顶元素・/top=pop2(top);/・删除栈顶元素・/returntop;/・返回栈顶指针・/)intempty2(STACK2*top)/・判栈是否为空・/(if(top-NULL)/・如果为空・/return1;/・返回1+/elsereturn0;/・否则返回0*/inttextl(char*s)|setbkcolor(BLUE);/・设置背景颜色为蓝色・/cleardevice0;/・清除屏幕・/setcolor(12);/・设置文本颜色为淡红色・/settextstyled,0,8);/*三重笔划字体,放大8倍・/outtextxy(120,120,s);/・输出字符串s*/setusercharsize(2,1,4,1);/*水平放大2倍,垂直放大4倍・/setcolor(15);/*设置文本颜色为・白色/settextstyle(3,0,5);/・无衬字笔划,放大5倍*/outtextxy(220,220,s);/・输出字符串s*/getchO;/・键盘输入任一字符・/ 54return;/・返回・/案例七数据结构CAI系统案例八进程调度ftinclude"stdio.h"ttincludestdlib.h#include"string,h”typedefstructnodecharname[10];/・进程标识符*/intprio;/・进程优先数・/intround;/・进程时间轮转时间片・/intcputime;/・进程占用CPU时间・/intneedtime;/・进程到完成还要的时间・/intcount;/・计数器・/charstate;/・进程的状态・/structnode*next;/・链指针・/}PCB;PCB"finish,*ready,*tail,*run;/・队列指针・/intN;/・进程数・//・将就绪队列中的第一个进程投入运行・/firstinO(ruロニready;/・就绪队列头指针赋值给运行头指针・/run-〉state='R';/・进程状态变为运行态・/ready=ready->next;/・就绪对列头指针后移到下•进程・/)/・标题输出函数・/voidprtl(chara){if(toupper(a)==,P*)/・优先数法・/printf("namecputimeneedtimoprioritystate 55/z);elseprintf("namecputimeneedtimecountroundstate 56");)/・进程PCB输出・/voidprt2(chara,PCB*q)if(toupper(a)==P')/・优先数法的输出・/printf("%-10s%-10d%-10d%-10d%c 57',q->name,q->cputime,q->needtime,q->prio,q->state);else/・轮转法的输出・/printf(*%-10s%-1Od%-1Od%-1Od%-1Od%-c 58”,q->name,q->cputime,q->needtime,q->count,q->round,q->state);}/・输出函数・/ 59voidprt(charalgo){PCB*p;prt1(algo);/・输出标题・/if(run!=NULL)/・如果运行指针不空・/prt2(algo,run);/・输出当前正在运行的PCB*/p=ready;/・输出就绪队列PCB*/while(p!=NULL)(prt2(algo,p);p=p->next;)p二finish;/・输出完成队列的PCB*/while(p!=NULL)(prt2(algo,p);p=p->next;}getchO;/・压任意键继续・/}/・优先数的插入算法・/insertl(PCB*q)(PCB*pl,*s,*r;intb;s=q;/・待插入的PCB指针・/pl=ready;/・就绪队列头指针・/r=pl;/*r做pl的前驱指针・/b=l;while((pl!=NULL)&&b)/*根据优先数确定插入位置・/if(pl->prio>=s->prio)(r=pl:pl=pl->next;elseb二〇;if(r!=pl)/・如果条件成立说明插入在r与pl之间・/{r->next=s;s->next=pl; 60)else(s->next=pl;/・否则插入在就绪队列的头・/ready二s;))/・轮转法插入函数・/insert2(PCB*p2)(tail->next=p2;/・将新的PCB插入在当前就绪队列的尾・/tail=p2;p2ー〉next=NULL;)/・优先数创建初始PCB信息・/voidcreatel(charalg){PCB*p;inti,time;charna[10];ready=NULL;/・就绪队列头指针*/finish=NULL;/・完成队列头指针・/run=NULL;/・运行队列指针・/printf("Enternameandtimeofprocess'n");/*输入进程标识和所需时间创建PCB*/for(i=l;i<=N;i++)(p=malloc(sizeof(PCB));scanf("%s",na);scanf(绘d”,&time);strcpy(p->name,na);p->cputime=O;p->needtime=time;pー〉state='w';pー〉prio=50-time;if(ready!=NULL)/・就绪队列不空调用插入函数插入*/insertl(p);elsepー〉next二ready;/・创建就绪队列的第一一个PCB*/ 61ready=p;)clrscr();outputofpriority: 62z/);printf("prt(alg):/*输出进程PCB信息・/run二ready;/・将就绪队列的第一个进程投入运行・/ready二ready->next;run->state='R';/・轮转法创建进程PCB*/voidcreate2(charalg)PCB*p;inti,time;charna[10];ready=NULL;finish=NULL;run=NULL;printf(/zEnternameandtimeofroundprocess'n");for(i=l;iく=N;i++)p=malloc(sizeof(PCB));scanf("姻",na);scanf(zz%d",&time);strcpy(p->name,na);p->cputime=O;p->needtime=time;p->count=0;/・计数器・/pー〉state二'w';pー〉round=2;/・时间片・/if(ready!=NULL)insert2(p);elsep->next=ready;ready=p;tail=p;clrscr();printf("outputofround'n"); 63prt(alg):/*输出进程PCB信息・/run=ready;/・将就绪队列的第-个进程投入运行・/ready=ready-〉next;run->state二’R';}/・优先数调度算法・/priority(charalg){while(run!=NULL)/・当运行队列不空时,有进程正在运行・/|run->cputime=run->cputime+l;run-〉needtime=run-〉needtime-1;run-〉prio=runー〉prio-3;/・每运行一次优先数降低3个单位・/if(run->needtime=0)/・如所需时间为〇将其插入完成队列・/(runー〉next二finish;finish=run;runー〉state=’ド;/・置状态为完成态・/run=NULL;/・运行队列头指针为空・/if(ready!=NULL)/・如就绪队列不空・/firstinO;/・将就绪对列的第一个进程投入运行・/)else/・没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列・/if((ready!=NULL)&&(runー〉prioくready-〉prio))(run-〉state二’ず;insertl(run);firstinO;/・将就绪队列的第一个进程投入运行・/}prt(alg);/*输出进程PCB信息・/}}/・时间片轮转法・/roundrun(charalg)(while(run!=NULL){run-〉eputime二run-〉cputime+1;run-〉needtime二run-〉needtimeT;run-〉count=run-〉count+1;if(runー〉needtimeニニ〇)/・运行完将其变为完成态,插入完成队列・/ 64{run-〉next二finish;finish=run;run->state=,F';run=NULL;if(ready!=NULL)firstinO;/・就绪对列不空,将第一个进程投入运行・/)elseif(run->count==run->round)/・如果时间片到・/{run->count=0;/・计数器置0*/if(ready!=NULL)/・如就绪队列不空・/(run->state=’『;/・将进程插入到就绪队列中等待轮转・/insert2(run);firstin();/・将就绪对列的第一个进程投入运行・/)}prt(alg);/・输出进程信息・/}}/・主函数・/main()(charalgo;/・算法标记*/clrscr();printfCtypethealgorithm:P/R(priority/roundrobin) 65'z);scanf("祝",&alg。);/*输入字符确定算法・/printf("Enterprocessnumber 66");scanf("%d",&N);/*输入进程数・/if(algoニニ’P'IIalgo=='p,)(createl(algo);/・优先数法・/priority(algo);)elseif(algoニニ‘R'IIalgoニニ'r')(create2(algo);/*轮转法・/roundrun(algo); 67案例九存储管理分区分配算法#include"stdio.h"#include"stdlib.h"#include"string』”^defineMAX32767typedefstructnode/・设置分区描述器・/{intaddress,size;structnode*next;}RECT;/*函数原型*/RECT*assignment(RECT*head,intapplication);voidacceptmentl(RECT*head,RECT*backl);voidacceptment2(RECT*head,RECT*backl);intbackcheck(RECT*head,RECT*backl);voidprint(RECT*head);/・变量声明・/RECT*head,*back,"assign1,*p;intapplicationl,maxblocknum;charway;/・主函数・/main()(charchoose[10];intcheck;head=malloc(sizeof(RECT));/・建立可利用区表的初始状态・/p=malloc(sizeof(RECT));headー〉size=MAX;head->address=0;headー〉next二p;maxblocknum=l;pー〉size=MAX;p->address=0;p->next=NULL;print(head);/・输出可利用表初始状态・/printf("Entertheway(bestorfirst(b/f) 68");/・选择适应策略・/scanfC%c,&way);do{printf("Entertheassignoraccept(as/ac) 69");scanf("%s",choose);/・选择分配或回收・/if(strcmp(choose,"as")=0)/*as为分配・/(printf("Inputapplication: 70");scanf("%d”,&app1ication1);/・输入申请空间大小・/assignl=assignment(head, 71application。;/・调用分配函数・/if(assignlー〉addressニニー1)/・分配不成功*/printf(^Toolargeapplication!,assignfails!! 72 73");elseprintf("Success!!ADDRESS=%5d 74”,assignl->address);/*分配成功*/print(head);/*输出・/)elseif(strcmp(choose,"ac")==0)/・回收・/{back=malloc(sizeof(RECT));printf("InputAdressandSize!! 75");scanf("%d%d",&back->address,&backー〉size);/・输入回收地址和大小・/check=backcheck(head,back);/*检查・/if(check==l)(if(tolower(way)='f')/・首先适应算法・/acceptment1(head,back);/*首先适应・/elseacceptment2(head,back);/*最佳适应・/print(head);}}}while(!strcmp(choose,'as")II!strcmp(choose,"ac,z));}/・分配函数・/RECT*assignment(RECT*head,intapplication)(RECT*after,"before,"assign;assign=malloc(sizeof(RECT));/"分配申请空间"/assign->size=application;assign->next=NULL;if(application>head->size|application<=0)assign->address二T;/"申请无效"/else{before=head;after=headー〉next;while(after-〉sizeくapplication)/"查找适应的结点"/(before=before-〉next;after二after-〉next; 76}if(after->size==application)/"结点大小等于申请大小则完全分配"/if(after-〉sizeニニheadー〉size)maxblocknum--;beforeー〉next二after->next;assignー〉address=afterー〉address;free(after);)else(if(after->size==head->size)maxblocknum一一;afterー〉size二afterー〉size-application;/・大于申请空间则截取相应大小分配・/assign-〉address=after->address+after->size;if(tolower(way)='b')/・如果是最佳适应,将截取后剩余结点重新回收到合适位置・/(before-〉next二after-〉next;back=after;acceptment2(head,back);})if(maxblocknum=0)/・修改最大数和头结点值・/{before=head;head->size=O;maxblocknum=l;while(before!=NULL)(if(before->size>head->size)(head->size=before->size;maxblocknum=l;}elseif(before->size==head->size)maxblocknum++;before=before-〉next;assignl=assign;returnassignl;/・返回分配给用户的地址・/ 77}voidacceptmentl(RECT*head,RECT*backl)/・首先适应・/(RECT"before,*after;intinsert;before=head;after=head->next;insert=O;while(!insert)/・将回收区插入空闲区表・/(if((after==NULL)||((backl->address<=after->address)&&(backl-〉address〉=before->address)))(before-〉next=back1;backl->next=after;insert=l;)else{before二beforeー〉next;after=after->next;)}if(backl-〉addressニニbeforeー〉address+beforeー〉size)/*与上一块合并*/(before-〉sizeニbefore-〉size+backl-〉size;beforeー〉next二backlー〉next;free(backl);backl=before;}if(after!二NULL&&(afterー〉addressニ二back1ー〉address+back1ー〉size)){/・与下ー块合并・/backl->size二backl->size+after->size;backl-〉next二after-〉next;free(after);}if(head->size 78elseif(head-〉sizeニニbackl-,size)maxblocknum++;}/・最佳适应,backl为回收结点的地址・/voidacceptment2(RECT*head,RECT*backl)RECT*before,*after;intinsert;insert=O;before=head;after=head-〉next;if(head->next==NULL)/・如果可利用区表为空・/(head->size=backl->size;headー)next二back1;maxblocknum++;backl->next=NULL;)else{while(after!=NULL)/・与上一块合并・/if(backl->address==after->size+after-〉address){before-〉next二after-〉next;back->size=after->size+back1ー〉size;free(after);after=NULL;}else(after=after->next;before=before-〉next;}before=head;after=headー〉next;while(after!=NULL)if(after-〉addressニニbacklー〉size+back1ー〉address)/・与下ー块合并・/(backlー〉size二backlー〉size+after-〉size;beforeー〉next=after-〉next;free(after); 79after=NULL;)else{before二beforeー〉next;after二after-〉next;before二head;/・将回收结点插入到合适的位置・/after二head-〉next;do{if(after=NULL||(after->size>backl->size))before->next二back1;back1ー〉next二after;insert=l;)else(before二before-〉next;after二afterー〉next;)}while(!insert);if(headー〉sizeくbacklー〉size)/・修改最大块值和最大块数・/{head->size=backl->size;maxblocknum++;)elseif(headー〉sizeニニbacklー〉size)maxblocknum++;voidprint(RECT*head)/・输出链表・/(RECT"before,*after;intindex,k;before二head-〉next;index二1;if(head->next==NULL)printf("N0partforassignment!! 80/z);else(printf("*****index*******address********ond*********sizo***** 81");while 82(before!=NULL)(printf(' 83");printf("%-13d%-13d%-13d%-13d 84,z,index,before->address,before->address+beforeー〉size-1,before->size);printf(" 85");index++;before=before-〉next;/・检查回收块的合法性,backl为要回收的结点地址・/intbackcheck(RECT*head,RECT*backl){RECT*before,*after;intcheck=l;if(backl->address<01|backl->sizeく〇)checkニ〇;/・地址和大小不能为负・/before=head-〉next;while((before!=NULL)&&check)/・地址不能和空闲区表中结点出现重叠・/if(((backl-〉addressくbefore-〉address)&&(backlー〉address+backl-〉size〉beforeー〉address))II((backlー〉address〉=before-〉address)&&(backl-〉addressくbeforeー〉address+beforeー〉size)))check=0;elsebefore=before-〉next;if(checkニニ0)printf("Errorinput!! 86");returncheck;/・返回检査结果・/案例十通讯录^include"stdio.h"/*1/0函数・/^include"stdlib.h"/・标准库函数・/^include"string,h"/・字符串函数*/^include"ctype.h"/・字符操作函数・/#defineM50/・定义常数表示记录数・/typedefstruct/・定义数据结构・/(charname[20];/・姓名・/charunits[30];/・单位・/chartele[10];/・电话・/}ADDRESS;/******以下是函数原型*******/intenter(ADDRESSt[]);/・输入记录・/voidlist(ADDRESSt[],intn);/・显示记录・/voidsearch(ADDRESSt[],intn);/*按姓名查找显示记录・/intdelete(ADDRESSt[],intn);/・删除记录・/intadd(ADDRESSt[],intn);/・插入记录・/voidsave(ADDRESSt[],intn);/・记录保存为文件・/intload(ADDRESS 87t[]);/・从文件中读记录・/voiddisplay(ADDRESStロ);/*按序号查找显示记录*/voidsort(ADDRESSt[],intn);/*按姓名排序・/voidqseek(ADDRESSt[],intn);/・快速査找记录・/voidcopyO;/・文件复制・/voidprint(ADDRESStemp);/・显示单条记录・/intfind(ADDRESSt[],intn,char*s);/*查找函数・/intmenu_select();/・主菜单函数・//******主函数开始*******/main()inti;ADDRESSadr[M];/*定义结构体数组・/intlength;/・保存记录长度・/clrscrO;/・清屏・/for(;;)/・无限循环・/(switch(menuselect())/・调用主菜单函数,返回值整数作开关语句的条件・/(case0:length=enter(adr);break;/・输入记录*/case1:list(adr,length);break;/・显示全部记录・/case2:search(adr,length);break;/・査找记录・/case3:length=delete(adr,length);break;/*删除记录・/case4:length=add(adr,length);break;/*插入记录・/case5:save(adr,length);break;/・保存文件・/case6:length=load(adr);break;/・读文件・/case7:display(adr);break;/・按序号显示记录・/case8:sort(adr,length);break;/・按姓名排序・/case9:qseek(adr,length);break;/・快速查找记录・/case10:copy();break;/・复制文件・/casell:exit(0);/・如返回值为11则程序结束・//*菜单函数,函数返回值为整数,代表所选的菜单项・/menu_select(){chars[80];intc;gotoxy(l,25);/*将光标定为在第25行,第1列・/ 88〃);/・提示压任意键继续・/printf〈pressanykeyentermenugetch();/・读入任意字符・/clrscrO;/・清屏・/gotoxy(1,1);printf("********************MENU********************* 89 90"); 91printf("printf(*printf("printf("printf("printf("printf("printf("printf("printf(*printf("printf("0.1.2.3.4.5.6.7.10.Enterrecord'n");Listthefile 92");Searchrecordonname 93");Deletearecord'd');addrecord 94");Savethefile'n");Loadthefile'n");displayrecordonorder'n");8.sorttomakenewfile'n");9.Quickseekrecord'n");copythefiletonewfile'n");11.Quit'n");printf(*********************************************** 95);do{printf(" 96Enteryouchoice(0~l1):");/・提示输入选项・/scanf("%s",s);/*输入选择项・/c=atoi(s);/・将输入的字符串转化为整型数・/}while(c<0||c>ll);/・选择项不在〇、11之间重输・/returnc;/・返回选择项,主程序根据该数调用相应的函数・/}/***输入记录,形参为结构体数组,函数值返回类型为整型表示记录长度・/intenter(ADDRESSt[])inti,n;char*s;clrscrO;/・清屏・/printf(" 97pleaseinputnum 98");/・提示信息・/scanf("%d",&n);/*输入记录数・/printf("pleaseinputrecord 99");/・提示输入记录・/printf("nameunittelephone'n");printf(* 100");for(i=0;iくn;i++)(scanf("%s%s%s",t[i].name,t[i].units,t[i].tele);/*输入记录・/printf(' 101");returnn;/・返回记录条数・/}/・显示记录,参数为记录数组和记录条数・/voidlist(ADDRESSt[],intn)inti;clrscr(); 102printf]nameunittelephone、イ’);printf(''n");for(i=0;i 103",t[i].name,t[i].units,t[i].tele);if((i+l)%10==0)/・判断输出是否达到10条记录*/printf("Pressanykeycontinue... 104");/*提不信,息*/getchO;/・压任意键继续・/)printf("************************end******************* 105");/・查找记录・/voidsearch(ADDRESSt[],intn)chars[20];/・保存待查找姓名字符串・/inti;/・保存查找到结点的序号・/clrscrO;/・清屏・/printf("pleasesearchname 106");scanf("%s”,s);/*输入待查找姓名・/i=find(t,n,s);/・调用find函数,得到ー个整数・/if(i>n-l)/・如果整数i值大于n-l,说明没找到・/printf("notfound 107");elseprint(t[i]);/・找到,调用显示函数显示记录・/}/・显示指定的・条记录・/voidprint(ADDRESStemp)clrscr();printf(" 108 109******************************************** 110");printf("nameunitprintf("printf("%-20s%-30s%-10s 111",temp,name,telephone 112");、ベ);temp,units,temp,tele);printf("**********************ond*********************** 113");/・查找函数,参数为记录数组和记录条数以及姓名s*/intfind(ADDRESSt[],intn,char*s)inti;for(i=0;iくn;i++)/・从第一条记录开始,直到最后一条・/if(strcmp(s,t[i].name)==0)/・记录中的姓名和待比较的姓名是否相等・/returni;/・相等,则返回该记录的下标号,程序提前结结束・/returni;/・返回i值・/}/・删除函数,参数为记录数组和记录条数・/ 114intdelete(ADDRESSt[],intn){chars[20];/・要删除记录的姓名・/intch=O;inti,j;printf(^pleasedeletedname 115");/・提示信息・/scanfs);/・输入姓名・/i=find(t,n,s);/・调用find函数・/if(i>n-l)/・如果i>n-1超过了数组的长度・/printf("nofoundnotdeleted 116");/・显示没找到要删除的记录・/else{print(t[i]);/・调用输出函数显示该条记录信息・/printf("Areyousuredeleteit(1/0) 117");/・确认是否要删除*/scanf("%d",&ch);/*输入ー个整数0或1*/if(ch==l)/・如果确认删除整数为1*/{for(j=i+1;j 118");printf("************************************************ 119");printf("nameunittelephone 120");printf(* 121");scanf("%s%s%s",temp,name,temp,units,temp,tele);/*输入插入信息・/printf(" 122");printf("pleaseinputlocatename 123");scanf(〃版”,s);/*输入插入位置的姓名・/i=find(t,n,s);/・调用find,确定插入位置*/for(j=n-l;j>=i;j-)/・从最后ー个结点开始向后移动一条・/ 124(strcpy(t[j+l].name,t[j].name);/*当前记录的姓名拷贝到后一条・/strcpyunits,t[j].units);/・当前记录的单位拷贝到后一条・/strcpytele,t[j].tele);/*当前记录的电话拷贝到后一条・/)strcpy(t[i].name,temp,name);/*将新插入记录的姓名拷贝到第i个位置*/strcpy(t[i].units,temp.units);/*将新插入记录的单位拷贝到第i个位置・/strcpy(t[i].tele,temp,tele);/*将新插入记录的电话拷贝到第i个位置・/n++;/・记录数加!*/returnn;/・返回记录数・/}/・保存函数,参数为结构体数组和记录数・/voidsave(ADDRESSt[],intn)(inti;FILE*fp;/・指向文件的指针・/if((fp=fopen("record,txt","wb"))==NULL)/・打开文件,并判断打开是否正常・/(printf("cannotopenfile 125");/・没打开*/exit(1);/・退出・/)printf(" 126Savingfile 127");/・输出提示信息・/fprintf(fp,"%d",n);/・将记录数写入文件・/fprintf(fp,"\r 128");/・将换行符号写入文件・/for(i=0;iくn;i++){fprintf(fp,"%-20s%~30s%-10s",t[i].name,t[i].units,t[i].tele);/・格式写入记录・/fprintf(fp,"\r 129");/・将换行符号写入文件・/}fclose(fp);/*关闭文件*/printf("****savesuccess*** 130");/・显示保存成功・/}/*读入函数,参数为结构体数组・/intload(ADDRESSt[])(inti,n;FILE*fp;/・指向文件的指针・/if((fp=fopen("record,txt","rb"))ニニNULL)/・打开文件・/printf("cannotopenfile 131");/・不能打开・/ 132exit(1);/・退出・/}fscanf(fp,"%d",&n);/・读入记录数・/for(i=0;iくn;i++)fscanf(fp,*%20s%30s%10s^,t[i].name,t[i].units,t[i].tele);/・按格式读入记录*/fclose(fp);/・关闭文件・/printf(*Youhavesuccessreaddatafromfile!!! 133*);/・显示保存成功・/returnn;/・返回记录数・/}/・按序号显示记录函数・/voiddisplay(ADDRESSt[]){intid,n;FILE*fp;/・指向文件的指针・/if((fp二fopen("record,txt","rb"))==NULL)/・打开文件・/(printf("cannotopenfile 134");/・不能打开文件・/exit(1);/・退出・/)printf("Enterordernumber... 135,z);/*显小信,息、*/scanf("紀",&id);/・输入序号・/fscanf(fp,"%d",&n);/・从文件读入记录数・/if(id>=0&&id 136〃);}elseprintf("no%dnumberrecord!!! 137",id);/*如果序号不合理显示信息・/fclose(fp);/・关闭文件・/}/・排序函数,参数为结构体数组和记录数・/voidsort(ADDRESSt[],intn)(inti,j,flag;ADDRESStemp;/・临时变量做交换数据用・/for(i=0;i 138strcpy(temp,tele,t[j].tele);strcpy(t[j].name,t[j+1].name);strcpy(t[j].units,t[j+l].units);strcpy(t[j].tele,t[j+1].tele);strcpy(t[j+1].name,temp,name);strcpy(t[j+1].units,temp,units);strcpy(t[j+1].tele,temp,tele);}if(flag=O)break;/*如果标志为0,说明没有发生过交换循环结束*/)printf(*sortsucess!!! 139");/・显示排序成功・/}/・快速查找,参数为结构体数组和记录数・/voidqseek(ADDRESSt[],intn)(chars[20];int1,r,m;printf(* 140Pleasesortbeforeqseek! 141");/*提示确认在查找之前,记录是否已排序*/printf("pleaseenternameforqseek 142");/*提小输入*/scanf("鯛",s);/・输入待查找的姓名・/l=0;r=n-l;/・设置左边界与右边界的初值・/while(K=r)/・当左边界く二右边界时・/(m=(l+r)/2;/・计算中间位置*/if(strcmp(t[m].name,s)=0)/・与中间结点姓名字段做比较判是否相等・/(print(t[m]);/・如果相等,则调用print函数显示记录信息・/return;/・返回・/}if(strcmp(t[m].name,s)<0)/*如果中间结点小・/1=m+1;/・修改左边界・/elser=m-l;/・否则,中间结点大,修改右边界*/)if(l>r)/・如果左边界大于右边界时・/printf(*notfound 143");/・显示没找到・//・复制文件・/voidcopy() 144charoutfile[20];/・目标文件名・/inti,n;ADDRESStemp[M];/*定义临时变量・/FILE*sfp,*tfp;/・定义指向文件的指针・/clrscr();/・清屏・/if((sfp二fopen("record.txt","rb"))ニニNULL)/・打开记录文件・/{printf("cannotopenfile 145");/・显示不能打开文件信息・/exit(1);/・退出・/}printf("Enteroutfilename,forexamplec:\\fl\\te.txt: 146");/・提示信息・/scanf("%s",outfile);/*输入目标文件名・/if((tfp=fopen(outfile,"wb"))==NULL)/・打开目标文件・/{printf("cannotopenfile 147");/・显示不能打开文件信息・/exit(l);/・退出・/)fscanf(sfp,"%d",&n);/・读出文件记录数・/fprintf(tfp,"%d",n);/・写入目标文件数・/fprintf(tfp,"\r 148");/・写入换行符・/for(i=0;i 149",temp[i].name,temp[i].units,temp[i].tele);/・读入记录・/fprintf(tfp,"%-20s%-30s%-10s 150",temp[i].name,temp[i].units,temp[i].tele);/・写入记录・/fprintf(tfp,"\r 151");/・写入换行符・/}fclose(sfp);/・关闭源文件・/fclose(tfp);/・关闭目标文件・/printf("youhavesuccesscopyfile!!! 152");/・显示复制成功・//*I/0函数・//・其它说明・//・字符串函数・//・屏幕操作函数・//・内存操作函数・//・字符操作函数・//・动态地址分配函数*/案例十一学生成绩管理#include"stdio.h"#include"stdlib.h"#include"string,h"#include"conio.h"#include"mem.h"#include“ctype.h/・定义常数*//・定义数据结构・/#include"alloc,h"^defineN3typedefstructzlcharno[ll];charname[15];intscore[N];floatsum;floataverage;intorder; 153structzl*next;}STUDENT;/・以ド是函数原型・/STUDENT*init();/・初始化函数・/STUDENT*create();/・创建链表・/STUDENT*delete(STUDENT*h):/・删除记录・/voidprint(STUDENT*h);/*显示所有记录・/voidsearch(STUDENT*h);/・查找・/voidsave(STUDENT*h);/*保存・/STUDENT*load():/・读入记录・/voidcomputer(STUDENT*h);/・计算总分和均分・/STUDENT*insert(STUDENT*h);/・插入记录・/voidappend();/・追加记录・/voidcopyO;/*复制文件*/STUDENT*sort(STUDENT*h);/・排序・/STUDENT*index(STUDENT*h);/・索引・/voidtotal(STUDENT*h);/・分类合计・/intmenu_select();/・菜单函数・//******主函数开始*******/main()inti;STUDENT*head;/・链表定义头指针・/head=init();/・初始化链表・/clrscrO;/・清屏・/for(;;)/・无限循环・/{switch(menu_select())/・调用主菜单函数,返回值整数作开关语句的条件・/{/・值不同,执行的函数不同,break不能省略・/caseO:head=init();break;/・执行初始化・/case1:head=create();break;/・创建链表・/case2:head=delete(head);break;/・删除记录・/case3:print(head);break;/・显示全部记录・/case4:search(head);break;/・查找记录・/case5:save(head);break;/・保存文件・/case6:head=load();break;/・读文件・/case7:computer(head);break;/・计算总分和均分・/ 154case8:head=insert(head);break;/*插入记录*/case9:copy0;break;/・复制文件・/case10:head=sort(head);break;/・排序・/case11:append();break;/・追加记录・/case12:head=index(head);break;/・索引・/case13:total(head);break;/・分类合计・/case14:exit(0);/・如菜単返回值为14程序结束・//・菜单函数,返回值为整数・/menu_select()char*menu[]={"***************MENU***************〃,/・定义菜单字符串数组・/〃0.initlist”,/・初始化・/"1.Enterlist",/・输入记录・/"2.Deletearecordfromlist",/・从表中删除记录・/"3.printlist",/・显示单链表中所有记录・/"4.Searchrecordonname",/・按照姓名查找记录・/〃5.Savethefile",/・将单链表中记录保存到文件中・/"6.Loadthefile",/・从文件中读入记录・/"7.computethescore",/・计算所有学生的总分和均分・/"8.insertrecordtolist",/・插入记录到表中・/"9.copythefiletonewfile",/・复制文件・/10.sorttomakenewfile",/・排序・/〃11.appendrecordtofile",/・追加记录到文件中・/"12.indexonnomber",/・索引・/"13.totalonnomber",/・分类合计・/"14.Quit"};/・退出・/chars[3];/・以字符形式保存选择号・/intc,i;/・定义整形变量・/gotoxy(1,25);/・移动光标・/printf("pressanykeyentermenu 155");/・压任一键进入主菜单・/getchO;clrscr();gotoxy(1,1);textcolor(YELLOW);/・输入任一键・//・清屏幕・//・移动光标・//・设置文本显示颜色为黄色・/textbackground(BLUE);/*设置背景颜色为蓝色・/gotoxy(10,2);/・移动光标・/putch(0xc9);/・输出左上角边框厂・/for(i=l;i<44;i++)putch(Oxcd);/*输出上边框水平线・/ 156putch(Oxbb);/・输出右上角边框1*/for(i=3;i<20;i++)gotoxy(10,i);putch(0xba);/・输出左垂直线・/gotoxy(54,i);putch(0xba);}/・输出右垂直线・/gotoxy(10,20);putch(0xc8);/・输出左上角边框、*/for(i=l;iく44;i++)putch(Oxcd);/*输出下边框水平线・/putch(Oxbc);/・输出右下角边框」・/window(ll,3,53,19);/・制作显示菜单的窗口,大小根据菜单条数设计・/clrscrO;/・清屏・/for(i=0;i<16;i++)/・输出主菜单数组・/{gotoxy(10,i+1);cprintf('%s”,menu[i]);)textbackground(BLACK);/・设置背景颜色为黑色・/windowd,1,80,25);/・恢复原窗口大小・/gotoxy(10,21);/*移动光标・/do{printf(" 157Enteryouchoice(〇へ14):");/・在菜单窗口外显示提示信息・/scanf("%s”,s);/*输入选择项・/c=atoi(s);/*将输入的字符串转化为整形数・/}while(c<0||c>14);/・选择项不在〇、14之间重输・/returnc;/・返回选择项,主程序根据该数调用相应的函数・/}STUDENT*init()(returnNULL;/・创建链表・/STUDENT*create()(inti;ints;STUDENT*h二NULL,*info;/*STUDENT指向结构体的指针・/for(;;)(info=(STUDENT*)malloc(sizeof(STUDENT));/・申请空间・/if(!info)/・如果指针info为空・/(printf(" 158outofmemory");/・输出内存溢出・/returnNULL;/・返回空指针・/ 159inputs("enterno:",info->no,11);/・输入学号并校验・/if(info->no[0]==@')break;/・如果学号首字符为@则结束输入・/inputs("entername:",infoー>name,15);/・输入姓名,并进行校验・/printf("pleaseinput%dscore 160",N);/*提示开始输入成绩・/s=0;/*计算每个学生的总分,初值为〇*/for(i=0;i 161");/・出错提示信息・/}while(info->score[i]>100infoー〉score[i]く〇);s=s+info->score[i];/*累加各门课程成绩・/}infoー〉SURFS;/・将总分保存・/info->average=(float)s/N;/・求出平均值・/info->order=0;/*未排序前此值为0*/infoー〉next=h;/・将头结点做为新输入结点的后继结点・/h=info;/・新输入结点为新的头结点・/)return(h);/・返回头指针・/}/・输入字符串,并进行长度验证・/inputs(char*prompt,char*s,intcount)(charp[255];do{printf(prompt);/・显示提示信息・/scanf("%s",p);/*输入字符串・/if(strlen(p)>count)printf(" 162toolong! 163");/・进行长度校验,超过count值重输入・/}while(strlen(p)>count);strcpy(s,p);/・将输入的字符串拷贝到字符串s中・/}/・输出链表中结点信息*/voidprint(STUDENT*h)(inti=0;/・统计记录条数・/STUDENT*p;/・移动指针・/clrscrO;/・清屏・/ 164P=h;/*初值为头指针・/printf(" 165 166 167****************************STUDENT******************************** 168"); 169printfCIrec|nOnameIsclIsc21sc3|sumaveIorderI 170^);printfC|一一ー11111111l 171つ;while(p!=NULL){i++;printfCI%3dl%-10s|%-15s|%4dl%4d|%4d|%4.2f|%4.2f%3d| 172”,i,p->no,p->name,pー)score[0],p->score[l],p->score[2],p->sum,p->average,p->order);p=p->next;}/・删除记录・/STUDENT*delete(STUDENT*h)(STUDENT*p,*q;/*p为查找到要删除的结点指针,q为其前驱指针・/chars[ll];/・存放学号・/clrscrO;/・清屏・/printfCpleasedeletedno 173");/・显示提示信息・/scanfC%s\s);/・输入要删除记录的学号・/q=p二h;/・给q和p赋初值头指针・/while(strcmp(p->no,s)&&p!=NULL)/・当记录的学号不是要找的,或指针不为空时・/{q=P;/・将P指针值赋给q作为P的前驱指针・/p二pー〉next;/・将p指针指向下一条记录・/}if(p==NULL)/・如果p为空,说明链表中没有该结点・/printf(z/ 174listno%sstudent'n”,s);else/*p不为空,显示找到的记录信息・/(printf("*****************************havefound*************************** 175");printf(*Ino|name|scl|sc21sc3sum|aveorder| 176");printfC|11111111 177zz);printf(*I%-10s|%-15s|%4d|%4d|%4d|%4.2f|%4.2f|%3d丨、n”,p->no,p->name,p->score[0],p->score[1],p->score[2],pー〉sum,p->average,p->order); 178getchO;if(p==h)h=p->next;elseprintf("********************************6nd******************************* 179");/・压任ー键后,开始删除*//*如果p=h,说明被删结点是头结点・//・修改头指针指向下一条记录・/qー》next=p->next;/・不是头指针,将p的后继结点作为q的后继结点・/free(p);/*释放p所指结点空间・/printfl 180havedeletedNo%sstudent 181,z,s);printf("Don'tforgetsave 182");/・提示删除后不要忘记保存文件・/)return(h);/・返回头指针・/}/・查找记录・/voidsearch(STUDENT*h)STUDENT*p;/・移动指针・/chars[15];/*存放姓名的字符数组・/clrscrO;/・清屏幕・/printf("pleaseenternameforsearch 183");scanf("%s",s);/・输入姓名・/p=h;/・将头指针赋给p*/while(strcmp(p->name,s)&&p!二NULL)/・当记录的姓名不是要找的,或指针不为空时・/p二pー〉next;/・移动指针,指向下ー结点・/if(p==NULL)/・如果指针为空・/printf(" 184listno%sstudent 185",s);/・显示没有该学生・/else/・显示找到的记录信息・/printf("InOorder| 186");printf(" 187 188*****************************havefound*************************** 189〃);name|scl|sc21sc31sum|aveprintf("|11111111 190");printf("I%-10s|%-15s|%4d|%4d|%4d|%4.2f|%4.2f|%3d| 191",p->no,p->name,p->score[0],p-〉score[1],p-〉score⑵,p->sum,p->average,p->order);printf("********************************end******************************* 192");/・插入记录・/STUDENT*insert(STUDENT*h)STUDENT*p,*q,*info;/*p指向插入位置,q是其前驱,info指新插入记录・/chars[ll];/・保存插入点位置的学号・/intsi,i; 193printfC'pleaseenterlocationbeforetheno 194");scanfs);/*输入插入点学号・/printf(zz 195pleasenewrecord'd');/・提示输入记录信息・/info=(STUDENT*)malloc(sizeof(STUDENT));/・申请空间・/if(!info)(printf(* 196outofmemory");/・如没有申请到,内存溢出・/returnNULL;/・返回空指针・/)inputs("enterno:",info->no,11);/・输入学号・/inputs("entername:",info->name,15);/・输入姓名・/printf("pleaseinput%dscore 197",N);/*提示输入分数・/sl=0;/*保存新记录的总分,初值为0*/for(i=0;iCN;i++)/*N门课程循环N次输入成绩・/(do{/・对数据进行验证,保证在0100之间・/printf("score%d:",i+1);scanf("%d",&info->score[i]);if(info->score[i]>100||infoー)score[i]く〇)printf("baddata,repeatinput'n");}while(info->score[i]>100Iinfo->score[i]く〇);si=sl+info-〉score[i];/・计算总分・/}info->sum=sl;/*将总分存入新记录中・/info->average=(float)sl/N;/・计算均分・/info-〉order=。;/・名次赋值0*/infoー〉next=NULL;/・设后继指针为空・/p=h;/*将指针赋值给P*/q=h;/・将指针赋值给q*/while(strcmp(p->no,s)&&p!=NULL)/・查找插入位置・/{q=P;/・保存指针P,作为下ー个P的前驱・/p=p->next;/・将指针P后移・/)if(p==NULL)/・如果p指针为空,说明没有指定结点・/if(p==h)/・同时p等于h,说明链表为空・/h=info;/・新记录则为头结点・/elseq->next=info;/*p为空,但p不等于h,将新结点插在表尾・/elseif(p==h)/*p不为空,则找到了指定结点・/info->next=p;/・如果p等于h,则新结点插入在第一个结点之前・/h=info;/・新结点为新的头结点・/}else(info->next=p;/・不是头结点,则是中间某个位置,新结点的后继为p*/q->next=info;/・新结点作为q的后继结点・/ 198)printf(' 199haveinserted%sstudent 200”,info->name);printf("Don'tforgetsave-- 201");/・提示存盘・/return(h);/・返回头指针・/}/・保存数据到文件・/voidsave(STUDENT*h)(FILE*fp;/*定义指向文件的指针・/STUDENT*p;/・定义移动指针・/charoutfile[10];/・保存输出文件名・/printf("Enteroutfilename,forexamplec:\\fl\\te.txt: 202");/・提示文件名格式信息・/scanf("%s",outfile);if((fp=fopen(outfile,"wb"))==NULL)/・为输出打开一个二进制文件,如没有则建立・/(printf("cannotopenfile 203");exit(1);)printf(" 204Savingfile 205");/・打开文件,提示正在保存*/p=h;/*移动指针从头指针开始・/while(p!=NULL)/*如p不为空・/(fwrite(p,sizeof(STUDENT),1,fp);/・写入一条记录・/p=p->next;/・指针后移・/}fclose(fp);/・关闭文件・/printf("savesuccess!! 206");/・显示保存成功・/}/・从文件读数据・/STUDENT*load()(STUDENT*p,*q,*h=NULL;/・定义记录指针变量・/FILE*fp;/・定义指向文件的指针・/charinfile[10];/・保存文件名・/printf("Enterinfilename,forexamplec:\\fl\\te.txt: 207");scanf("%s",infile);/・输入文件名・/if((fp=fopen(infile,"rb"))==NULL)/*打开一个二进制文件,为读方式・/{printf("cannotopenfile 208");/・如不能打开,则结束程序・/ 209exit(1);}printf(* 210Loadingfile! 211");p=(STUDENT*)malloc(sizeof(STUDENT));/・申请空间・/if(!p){printf("outofmemory! 212");/・如没有申请到,则内存溢出・/returnh;/*返回空头指针・/}h=p;/・申请到空间,将其作为头指针・/while(!feof(fp))/・循环读数据直到文件尾结束・/{if(1!=fread(p,sizeof(STUDENT),1,fp))break;/・如果没读到数据,跳出循环・/p->next=(STUDENT*)malloc(sizeof(STUDENT));/・为下ー个结点申请空间・/if(!p->next)(printf("outofmemory! 213");/・如没有申请到,则内存溢出・/returnh;)q=p;/・保存当前结点的指针,作为下ー结点的前驱・/p=p->next;/・指针后移,新读入数据链到当前表尾・/)q->next=NULL;/・最后一个结点的后继指针为空・/fclose(fp):/・关闭文件・/printf("—Youhavesuccessreaddatafromfile!!!— 214");returnh;/*返回头指针・/}/・追加记录到文件*/voidappend()(FILE*fp;/・定义指向文件的指针・/STUDENT*info;/・新记录指针・/intsi,i;charinfile[10];/・保存文件名・/printf(* 215pleasenewrecord'n");info=(STUDENT*)malloc(sizeof(STUDENT));/・申请空间・/if(!info)printf(* 216outofmemory");/・没有申请到,内存溢出本函数结束・/return;inputs("enterno:",info->no,11);/・调用!nputs输入学号・/ 217inputs("entername:z,,info->name,15);/・调用!nputs输入姓名・/printf("pleaseinput%dscore 218",N);/*提示输入成绩・/sl=0;for(i=0;i 219");}while(info->score[i]>100info-〉score[i]く〇);/・成绩数据验证・/si二sl+info-〉score[i];/・求总分・/)infoー〉sum=sl;/・保存总分・/info->average=(float)sl/N;/・求均分・/info-〉order=0;/・名次初始值为0*/info-〉next=NULじ/・将新记录后继指针赋值为空・/printf("Enterinfilename,forexamplec:\\fl\\te,txt: 220");scanf("%s",infile);/*输入文件名・/if((fp=fopen(infile,"ab"))==NULL)/・向二进制文件尾增加数据方式打开文件・/{printf("cannotopenfile 221");/・显示不能打开・/exit(l);/・退出程序・/}printf(z/ 222Appendingrecord! 223");if(l!=fwrite(info,sizeof(STUDENT),1,fp))/・写文件操作・/{printf("filewriteerror! 224");return;/・返回・/}printf("appendsucess!! 225");fclose(fp);/*关闭文件*/}/・文件拷贝・/voidcopy(){charoutfile[10],infile[10];FILE*sfp,*tfp;/・源和目标文件指针・/STUDENT*p二NULL;/・移动指针・/clrscrO;/・清屏・/printf(""Enterinfilename,forexamplec:\\fl\\te.txt: 226");scanf("%s",infile);/・输入源文件名・/ 227if((sfp=fopen(infile,"rb"))==NULL)/*二进制读方式打开源文件・/|printf(*cannotopeninputexit(O);}.printf("Enteroutfilename,forexamplec:\\fl\\te.txt: 228");/・提示输入目标文件名・/scanf("%s",outfile);/・输入目标文件名・/if((tfp=fopen(outfile,"wb"))—NULL)/・二进制写方式打开目标文件・/{printf("cannotopenoutputfile 229"):exit(0);}while(!feof(sfp))/・读文件直到文件尾・/{if(1!=fread(p,sizeof(STUDENT),1,sfp))break;/・块读・/fwrite(p,sizeof(STUDENT),1,tfp);/・块写・/}fclose(sfp);/・关闭源文件・/fclose(tfp);/・关闭目标文件・/printf("youhavesuccesscopyfile!!! 230");/・显示成功拷贝・/}/・排序・/STUDENT*sort(STUDENT*h)(inti=0;/・保存名次・/STUDENT*p,*q,*t,*hl;/・定义临时指针・/hl=h->next;h->next=NULL;while(hl!=NULL)t=hl;hl=hl->next;p=h;q=h;/・将原表的头指针所指的下ー个结点作头指针・//*第一个结点为新表的头结点・//・当原表不为空时,进行排序・//・取原表的头结点・//・设定移动指针P,从头指针开始・//・设定移动指针q做为P的前驱,初值为头指针・//・原表头结点指针后移・/while(t->sum 231q=p;p=p->next;/・待排序点值小,则新表指针后移・/if(p==q)/*p==q,说明待排序点值大,应排在首位・/t->next=p;/・待排序点的后继为P*/ 232h=t;/・新头结点为待排序点・/)else/・待排序点应插入在中间某个位置q和p之间,如p为空则是尾部・/(t->next=p;/*t的后继是p*/q->next=t;/*q的后继是t*/}}P=h;/・已排好序的头指针赋给p,准备填写名次・/while(p!=NULL)/・当p不为空时,进行下列操作*/i++;/・结点序号・/p->order=i;/・将名次赋值・/p=p->next;/・指针后移・/}printf(*sortsucess!!! 233");/・排序成功・/returnh;/・返回头指针・/}/・计算总分和均值・/voidcomputer(STUDENT*h)(STUDENT*p:/・定义移动指针・/inti=0;/*保存记录条数初值为〇・/longs=0;/・总分初值为〇・/floataverage=0;/・均分初值为0*/p=h;/・从头指针开始・/while(p!=NULL)/・当p不为空时处理・/(s+=p->sum;/・累加总分*/i++;/・统计记录条数・/p=p->next;/・指针后移・/}average=(float)s/i;/・求均分,均分为浮点数,总分为整数,所以做类型转换・/printf(" 234~~Allstudentssumscoreis:%ldaverageis%5.2f 235<,,s,average);}/・索引・/STUDENT*index(STUDENT*h){STUDENT*p,*q,*t,*hl;/・定义临时指针・/hl=h->next;/・将原表的头指针所指的下ー个结点作头指针・/h->next=NULL;/*第一个结点为新表的头结点・/while(hl!=NULL)/・当原表不为空时,进行排序・/t=hl;/・取原表的头结点・/hl=hl->next;/・原表头结点指针后移・/p=h;/・设定移动指针p,从头指针开始・/q=h;/*设定移动指针q做为p的前驱,初值为头指针・/while(strcmp(t->no,p->no)〉0&&p!=NULL)/・作学号比较・/(q=P;/・待排序点值大,应往后插,所以新表指针后移・/p=p->next;} 236if(p==q)/*p==q,说明待排序点值小,应排在首位・/(t->next=p;/・待排序点的后继为p*/h=t;/・新头结点为待排序点・/}else/・待排序点应插入在中间某个位置q和p之间,如p为空则是尾部*/(t->next=p;/*t的后继是p*/q->next=t;/*q的后继是t*/})printf("indexsucess!!! 237");/・索引排序成功・/returnh;/・返回头指针・/)/*分类合计・/voidtotal(STUDENT*h)(STUDENT*p,*q;/*定义临时指针变量・/charsno[9],qno[9],*ptr;/・保存班级号的・/floatsi,ave;/・保存总分和均分・/inti;/・保存班级人数・/clrscrO;/・清屏・/printf(w 238 239*******************Total***************** 240");printf("-classsumaverage'n);P=h;/・从头指针开始・/while(p!=NULL)/*当p不为空时做下面的处理・/(memcpy(sno,p->no,8);/・从学号中取出班级号・/sno[8]='、0’;/・做字符串结束标记・/q=p->next;/・将指针指向待比较的记录・/sl=pー〉sum;/・当前班级的总分初值为该班级的第-条记录总分・/ave=p->average;/*当前班级的均分初值为该班级的第一条记录均分・/i=l;/*统计当前班级人数・/while(q!=NULL)/・内循环开始・/memcpy(qno,q->no,8);/・读取班级号・/qno[8]-\0;/・做字符串结束标记・/if(strcmp(qno,sno)-0)/・比较班级号・/(sl+=q->sum;/・累加总分・/ave+=q->average;/・累加均分・/i++;/・累加班级人数・/q=q->next;/・指针指向下一条记录・/)elsebreak;/・不是ー个班级的结束本次内循环・/)printf(ff%s%10.2f%5.2f 241”,sno,si,ave/i); 242if(qニニNULL)break;/・如果当前指针为空,外循环结束,程序结束・/elseP=q;/・否则,将当前记录作为新的班级的第一条记录开始新的比较・/}printf(" 243");案例十二エ资管理#include"stdio.h"/*1/0函数・/#include"bios,h""ROM基本输入输出函数・/#include"dos.h"/*dos接口函数・/#include"conio./・屏幕操作函数・/#include"stdlib.h"/・其它说明・/#include"string,h"/・字符串函数・/#include"mem.h"/・内存操作函数・/#include"ctype.h"/・字符操作函数・/#include"alloc*h"/・动态地址分配函数*//****变量定义*******/typedefstructzl/・定义数据结构*/{charno[ll];/*编号・/charname[15];/・姓名・/floatjbgz;/・基本工资・/floatkoukuan;/・扣款・/floatyfgz;/・应发エ资・/floatshuijin;/・税金・/floatsfgz;/・实发エ资・/structzl*prior;/・前驱指针・/structzl*next;/・后继指针・/}SALARY;/・结构体类型名・/structzl*First;/・双链表头指针・/structzl*Last;/・双链表尾指针・//******函数原型*********/voidinit();/*初始化・/voidcreate();/・创建链表・/voidcalc();/*计算应发エ资・/voiddelete();/*删除・/voidsearch();/*查找・/voidsave();/・保存文件・/voidload();/・读取文件*/voidcomputer();/*计算所需各种票面张数・/voidinsert();/*插入・/voidappend();/*追加・/ 244voidcopy0;/・复制文件・/voidsort();/・排序・/voidindex0;/*索引・/voidtotal();/・分类合计・/voidlist();/*显示所有数据・/voidprint(SALARY*p);/・输出单条记录・/voiddisplay();/・随意逐条显示・/floatfax(floatx);/・计算税金・/intmenu_select();/・主菜单・//*******主函数开始**********/main()inti;clrscr();for(;;){switch(menu_select())/・调用菜单函数返回一个整数值・/{case0:init();break;/・初始化・/case1:create();break;/・输入数据创建双链表・/case2:list();break;/・显示所有数据・/case3:display();break;/・单条显示・/case4:calc();break;/・计算实发エ资・/case5:search();break;/・查找职エ信息数据・/case6:delete();break;/・删除记录・/case7:insert();break;/・插入记录・/case8:append();break;/・追加记录・/case9:save();break;/・保存文件・/case10:load();break;/*读取文件*/case11:copy();break;/・复制文件・/case12:sort();break;/*按实发エ资升序排序*/case13:computer();break;/・计算所需票面数・/case14:index();break;/*按职エ号索引*/case15:total();break;/*按部门求合计・/case16:exit(0);/・退出・/)})/・菜单函数,函数返回值为整型,代表所选的菜单项・/menuselect(){char*f口={/・定义菜单字符串数组・/***************MENU*************”,/*菜单的标题行・/ 245"o.initlist”,/・初始化双链表*/"1.Enterlist”,/・输入数据,创建双链表・/“2.Listall 246",/・显示所有记录・/"3.Displayrecordbystep”,/・显示单条记录・/"4.Calcthesalary*,/*计算实发エ资・/"5.Searchrecordonname",/*查找i己录*/"6.Deletearecord",/・删除记录・/"7.Insertrecordtolist",/*插入t己求・/“8.Appendrecordtofile",/・追加记录・/"9.Savedatatothefile",/・保存文件・/“10.Loaddatafromthefile",/・读取文件・/"11.Copythefiletonewfile",/・复制文件・/"12.Sortonsfgz",/・排序・/"13.Computerticketnumber",/・计算所需票面数・/"14.Indexonnumber”,/・索引・/"15.Totalonnumber”,/・分类合计・/"16.Quit"};/・退出・/chars[80];inti;intkeyニ〇;/・记录所压键值・/intc=0;gotoxy(1,25);/・移动光标・/printf("pressanykeyentermenu 247");/・压任意键进入主菜单・/getch();clrscr();/・清屏・/textcolor(YELLOW);/・设置文本颜色为黄色・/textbackground(BLUE);/・设置背景颜色为兰色・/gotoxy(10,2);putch(Oxda);/・输出左上角边框厂・/for(i=l;i<44;i++)putch(0xc4);/・输出上边框水平线・/patch(Oxbf);/・输出右上角边框[*/for(i=3;i<22;i++)/・输出左右两边的垂直线・/(gotoxy(10,i);putch(0xb3);gotoxy(54,i);putch(0xb3);)gotoxy(10,22);patch(OxcO);/・输出左上角边框「*/for(i=l;i<44;i++)patch(0xc4);/・输出下边框水平线・/putch(0xd9);/・输出右下角边框」・/window(lls3,53,21);/・制作显示菜单的窗口,大小根据菜单条数设计・/clrscrO;/・清屏・/for(i=0;i<18;i++){gotoxy(10,i+1);cprintf("版",f[i]);/・输出菜单项数组・/}i=l; 248gotoxy(10,2);/・设置默认选项在第一项・/textbackground(LIGHTGREEN);/・设置背景颜色为浅绿・/cprintf(线s”,f[1]);/*输出菜单项,表示选中・/gotoxy(10,2);/*移动光标到菜单的第一项・/while(key!=13)/・所压键不是回车键时・/(while(bioskey(1)=0);/・查询是否压下了一个键・/key=bioskey(0);/・返回下ー个在键盘压下的键・/key=key&0xff?key&0xff:key»8;/・对所压的键进行判断・/gotoxy(10,i+1);textbackground(BLUE);/・设置背景颜色为蓝色・/cprintf(〃%s〃,f[i]);/・输出菜单项・/if(key=72)i=i=l?17:iT;/・如压向上光标键t,i减1,如已到第一行再上移,则到最后一行・/if(key==80)i=i=17?l:i+l;/・如压向下光标键I,i加1,如已到最后一行再下移,则到第一行・/gotoxy(10,i+1);/・光标移动i的下ー项・/textbackground(LIGHTGREEN);/・将背景颜色设为浅绿・/cprintf("%s",f[i]);/・输出菜单项・/c=i-l;/・给代表菜单选项的整数赋值・/)textbackground(BLACK);/・设置背景颜色为黑色・/windowd,1,80,25);/*恢复原窗口大小・/returnc;/・返回代表菜单选项的整数值*/}/・初始化函数・/voidinit()First=NULL;Last=NULL;}/*输入数据,创建双链表・/voidcreate()(intx;/・记录行坐标・/inti;/・记录输入记录数・/intflag=0;/・做结束标记・/floattemp;/・定义临时变量・/SALARY*info,*p;/*定义临时变量・/if(First!=NULL)init();/*如果头指针为空,调用初始化函数・/p二First;/・从头指针开始・/for(;;)(if(flag=l)break;/*如果flag=L结束输入・/i=0;x=0;/*确定移动的行坐标・/ 249clrscrO;/・清屏・/gotoxy(1,3);printf("*************gongziguan1i*************");/*输出标题*/gotoxy(1,4);printf(*—Enter@end—");/・提示输入@结束・/gotoxy(1,5);printf〇ド);/・输出表格的起始线・/gotoxy(1,6);printf("Ino丨name|jbgz|");/・输出字段标题,注意空格数for(;;){gotoxy(1,7+x);printfC|11丨”);/・输出表格的水平线・/info=(SALARY*)malloc(sizeof(SALARY));/・申请ー个记录空间・/if(!info)(printf(" 250outofmemory");/・如没有得到空间,输出内存溢出信息・/exit(0);/・退出程序・/}infoー〉next二NULL;/・新结点的后继为空・/info->prior=NULL;/・新结点的前驱为空・/gotoxy(1,8+x);printf("");/・输出数据间的分割线・/gotoxy(12,8+x);printfgotoxy(29,8+x);printf(丁);gotoxy(38,8+x);printf("ド);gotoxy(2,8+x);/・光标到输入编号位置*/inputs(info->no,10);/*输入编号,并验证长度不超过10*/if(info->no[〇]=='@')(flag=l;break;}/・编号首字符为@结束输入・/gotoxy(13,8+x);/*光标到输入姓名位置・/inputs(info->name,14);/・输入姓名,并验证长度不超过14*/gotoxy(30,8+x);/*光标到输入基本工资位置・/scanf&temp);/・输入基本工资到临时变量・/info->jbgz=temp;/・基本工资赋值・/info->koukuan=0;/・初始扣款为〇,待计算工资时输入・/info->sfgz=0;/*初始实发エ资为〇,待计算工资时计算・/info->shuijin=O;/・初始税金为〇,待计算工资时计算・/infoー>yfgz=0;/・初始应发エ资为0,待计算工资时计算・/if(p二NULL)/・如果p为空,说明输入的是第一个结点・/(First=Last=info;/・头指针和尾指针・/First->prior=NUlX;/・头指针的前驱是空・/Last->next=NULL;/・尾指针的后继是空・/)else/・插入的结点不是第一结点,则插入在头结点之前・/(info->next=p;/・新结点的后继指向原来的头结点・/infoー〉prior=pー〉prior;/・新结点的前驱指向原来的头结点的前驱・/p->prior=info;/*原来结点的前驱指向新结点・ 251/}p=info;/・新结点变为p结点,暂时的头结点・/First=info;/・新结点变为头结点・/x+=2;/*因为水平线,将光标下移两行・/gotoxy(1,8+x);i++;/・输入记录数加1*/if(i%9=-0)break;/*输入9个记录,换ー页输入・/)gotoxy(1,8+x);}printffI11ド);/・输出结尾水平线・/}/*字符串输入和验证函数・/inputs(char*s,intcount)charp[255];do{scanf('%s”,p);/*输入字符串・/if(strlen(p)>count)printfC 252toolong! 253");/・进行长度校验,超过count值重输入*/}while(strlen(p)>count);strcpy(s,p);/・将输入的字符串拷贝到字符串s中・/}/・显示链表・/voidlist(){inti=0,n;/・记录输出行数・/SALARY*p;/*定义移动指针・/clrscrO;/・清屏・/p二First;/・从头指针开始・/while(i%10-0&&p!=NULL)/・外循环控制换页・/(i=0;/・记录ー页的输出行数・/clrscrO;/・清屏・/printf("ヽn 254 255");/・换行三次*/pr]ntf(*************************************SALARY*********************************** 256");/・输出大标题・/name|jbgz|koukuanyfgz|shuijin|printf(*InO|sfgz| 257");/・输出字段标题・/ 258printf(*I11111| 259");/・输出水平线・/while(p!=NULL)/*当p不为空时・/(printfC|%-10s|%-15s|%9.2fI%9.2f|%9.2f|%9.2f|%9.2f| 260”,p->no,p->name,p->jbgz,p->koukuan,p->yfgz,p->shuijin,p->sfgz);p=p->next;/・指针后移・/i++;/・输出行数加1*/if(i%10==0)break;/・如果满10行,跳出内循环・/prjntf("****************************************end*********************************** 261");/・输出本页的结束行・/printf("Pressanykeycongtinue... 262");getch();/・输出ー页暂停一下,压任意键继续・/}/・返回到外循环,准备下ー页的输出・/}/・单条显示记录・/voiddisplay()(intch;/・菜单选项字符・/SALARY*p;/・定义临时指针・/clrscrO;/・清屏・/p二First;/・从头指针开始・/if(p=NULL)/・指针为空,即链表为空,返回主函数・/(printf(*recordisempty! 263,z);return;}else(print(p);/・调用输出函数显示头结点信息・/for(;;)/・循环开始・/{printf(' 264 265O.Quit1.Prior2.Next3.First4.Last 266 267");/・菜单项Quit退出Prior前驱Next后继First第一条Last最后一-条・/printf(* 268pleaseselect〇、4:");/・提示输入菜单选项〇、4*/scanf("观",&ch);/・输入菜单选项〇、4*/if(ch==0)break;/・如果选项为〇,退出・/switch(ch)/・开关语句根据选项字符判断・/(case1:p=p->prior;if(p==NULL)p=First;break;/・指向前驱,没有前驱指向第一个・/case2:p=p->next;if(p==NULL)p=Last;break;/・指向后继,没有后继指向最后ー个・/ 269case3:p=First;break;/・指向第一个结点・/case4:p=Last;break;/・指向最后一个结点・/}print(p);/・调用输出函数显示指针所指结点信息・//・输出指针所指结点信息・/voidprint(SALARY*p)(if(p)/・如果指针不为空,则显示信息・/clrscrO;/・清屏・/printf(" 270 271 272");/・换行・/printf(************************************SALAR************************************* 273");/・输出标题信息・/printf(z/1no|name|jbgz|koukuan|yfgzshuijinsfgz| 274");/・输出字段标题*/printf("I111111——| 275〃);/・输出分割线・/printf("I%—10sI%—15sI%9.2f|%9.2f|%9.2f|%9.2f|%9.2f| 276\p->no,p->name,p->jbgz,p->koukuan,p->yfgz,p->shuijin,pー>sfgz);/・输出结点信息・/******* 277");/・输出结束标记・//・计算实发エ资・/voidcalc()(intx;/・行坐标・/intiニ0;/・记录数・/floattemp;/・临时变量扣款・/SALARY*p;/・移动指针・/clrscrO;/・清屏・/p二First;/・从头指针开始・/while(p!=NULL)/・当p不为空时,也就是有记录时,外循环控制换页・/x=0;clrscrO;gotoxy(1,3);printf("***************************gongzigiianli***********************************・〃);/・输出标题・/ 278gotoxy(1,5);printf(“I—丨”);gotoxy(1,6);/・下面输出字段标题・/printf("Ino|name|jbgz|koukuan|yfgzshuijin|sfgzド);while(p!=NULL)/・当p不为空时,也就是有记录时,内循环控制处理9条・/gotoxy(1,7+x); 279printflI1丨”);gotoxyd,8+x);printf(丁);つ;つ;つ;つ;つ;つ;つ;gotoxy(12,8+x);printf("gotoxy(29,8+x);printf("gotoxy(38,8+x);printf("gotoxy(49,8+x);printf("gotoxy(58,8+x);printf("gotoxy(67,8+x);printf("gotoxy(76,8+x);printf("gotoxy(2,8+x);printf("%TOs",pー>no);/・输出编号・/gotoxy(13,8+x);printf("%-15s”,pー>name);/・输出姓名・/gotoxy(30,8+x);printf("%.2f",p->jbgz);/・输出基本工资・/gotoxy(39,8+x);scanf("%f",&temp);/・输入扣款・/p->koukuan=temp;/・扣款字段赋值・/pー〉yfgz二pー〉jbgz-pー〉koukuan;/・计算应发エ资二基本工资ー扣款・/gotoxy(50,8+x);printfC%.2f",p->yfgz);/・输出应发エ资・/gotoxy(59,8+x);pー〉shuijin=(pー〉yfgzT000)*fax(pー〉yfgz);/・否则按税率计算税金・/printf("%.2f",p->shuijin);/・输出税金・/gotoxy(68,8+x);p->sfgz=p->yfgz-p->shuijin;/・计算实发エ资・/printf("%-8.2f",p-〉sfgz);/・输出实发エ资・/x+=2;/・行坐标下移两行・/i++;/・记录数加1*/if(i%9ニニ〇)break;/・记录数超过9条,跳出内循环・/p二pー〉next;/・指针后移,处理下一条・/}gotoxy(1,7+x);printf("I11一ー1 280つ;/・输出结束行・/printf("Pressanykeycongtinue... 281");getchO;)/・根据应发エ资,计算税率・/floatfax(floatx)floatfl;if(x<1000)return0;/・小于100〇,返回。・/switch((int)(x/1000))( 282casel:fl=0.05;break;/*1000"1999,返回0.05*/case2:f1=0.1;break;/*2000~2999,返回0.1*/case3:f1=0.15;break;/*300〇〜3999,返回0.15*/case4:fl=0.2;break;/*400〇〜4999,返回0.2*/default:f1=0.3;break;/*5000以上,返回0.3*/)returnfl;)/*计算票面张数・/voidcomputer(){SALARY*p;inti=0,a[7]={0},tl00,t50,t20,tlO,t5,t2,tl;/*设置数组和临时变量保存票面张数・/floatt;/・过渡变量,保存当前剩余工资・/p二First;/・移动指针从头指针开始・/while(p!=NULL)/*当p不为空时・/(1100=(int)p->sfgz/100;/・计算100元张数・/a[0][0]+1100;/*累加保存・/t=p->sfgz-t100*100;/・剩余エ资・/t50=(int)(t/50);/・计算50元张数・/a[l]=a[l]+t50;/・累加保存・/t=t-t50*50;/・剩余エ资・/t20=(int)(t/20);/・计算20元张数・/a[2]=a[2]+t20;/・累加保存・/t=t-t20*20:/・剩余エ资・/tlO=(int)(t/10);/*计算10元张数・/a[3]=a[3]+tl0;/*累加保存*/t=t-tio*io;/・剩余エ资・/t5=(int)(t/5);/*计算5元张数・/a[4]=a[4]+t5;/・累加保存・/t=t-t5*5;/・剩余エ资・/t2=(int)(t/2);/・计算2元张数・/a⑸=a[5]+t2;/*累加保存*/t=t-t2*2;/・剩余エ资・/tl二(int)⑴;/・计算1元张数・/a[6]=a[6]+tl;/*累加保存・/p=p->next;/・指针后移,处理下一条记录・/clrscrO;/・清屏・/printf("ヽn 283 284***********ticketnumber*************** 285");/・输出标题・/ 286printf("-100502010521'n");/・输出张数标题・/for(i=0;i<7;i++)printf("炳d",a[i]);/・输出所需的张数*/printf(" 287");/・换行・/}/・按编号查找记录・/SALARY*find(char*no){SALARY*p;/*定义移动指针・/p=First;/・从头指针开始・/while(p)/・当p不为空时・/{if(!strcmp(no,p->no))returnp;/・比较相等,查找成功,返回指针・/p=p->next;/・不相等指针后移・/}printf("notfound 288");/・没有找到・/returnNULL;/・返回为空指针・/}/・删除结点・/voiddelete()(SALARY*p;/*定义临时变量,p指向要删除的结点p*/chars[ll];/・要删除结点的编号・/clrscrO;/・淸屏・/printf("pleasedeletedno 289");/・提示输入信息・/scanf("%s",s);/・输入要删除的职エ编号・/if((p=find(s))!=NULL)/・调用查找函数,如果找到做下面的处理・/(if(First==p)/・如果是第一个结点・/{First=p->next;/・将头指针指向其后继结点・/if(First)/・如头指针不为空・/First->prior=NULL;/*将头结点的前驱设为空・/elseLast=NULL:/・否则头为空,尾也为空・/}else/・删除的不是第一个结点・/(p->prior->next=p->next;/*p的前驱的后继指向p原来的后继・/if(p!=Last)/*如果 290p不是最后个结点・/p->next->prior=p->prior;/*p后继的前驱指向p原来的前驱・/elseLast=p->prior;/・如p是最后一个结点,修改尾指针为p的前驱・/}free(p);/・删除结点后,不要忘记释放空间・/printf(" 291havedeleted%sSALARY 292",s);printf("Don'tforgetsave 293");}}/・按姓名查找结点・/voidsearch(){SALARY*p;/*移动指针*/chars[15];/・保存姓名・/clrscrO;/・清屏・/printf("pleaseenternameforsearch 294");/・提取输入*/scanf(w%s",s);/・输入要查找人的姓名・/p=First;/・移动指针从头指针开始・/while(strcmp(p->name,s)&&p!=NULL)/・做比较判断*/p-p->next;/・没找到,指针后移继续查找・/if(p==NULL)/・指针为空,说明没有找到・/printf(" 295listno%sSALARY 296",s);/・显示没找到信息・/else(printf(" 297 298");/・换行・/print(p);/・查找成功,调用输出函数输出指针p所指记录・/))/・插入结点・/voidinsert()(SALARY*p,*inf。;/*info为新结点,p为新结点的后继・/chars[ll];/*保存查找的姓名・/floattemp;/・临时变量・/clrscrO;/・清屏・/printf("pleaseenterlocationbeforetheno'n");/*提示输入在哪个结点之前插入*/scanf(线s",s);/・输入指定结点的编号・/printf(" 299pleasenewrecord'n");/・提示输入记录・/clrscr();/・清屏・/gotoxy(l,3);/・定位光标,按表格形式输入新结点信息・/printf("**************gongziguardi************");gotoxy(1,5);printfC"Iド);gotoxy(1,6);printfIno|name|jbgz1つ;gotoxy(1,7);printfC|111");info=(SALARY*)malloc(sizeof(SALARY));/・申清空间・/if(!info)(printfC 300outofmemory*);/・如没有得到空间,内存溢出・/exit(O);/・退出程序・/)info->next-NULL;/・新结点的后继为空・/info->pri〇『NULL;/・新结点的前駆为空・/gotoxy(1,8);printf("|");gotoxy(12,8);printfCl");gotoxy(29,8);printf("|");gotoxy(38,8);printf("");gotoxy(2,8);inputs(info->no,10);/・输入新结点的编号,并校验・/gotoxy(13,8);inputs(info->name,14);/*输入新结点的姓名,并校验・/gotoxy(30,8);scanf(〃%f”,fitemp);/*输入基本工资・/info->jbgz=temp;/・给基本工资字段赋值・/info->koukuan=0;/・扣款初始为〇・/ 301info->yfgz=0;/・应发エ资初始为0*/info->shuijin=O;/・税金初始为0*/info->sfgz=0;/・实发エ资初始为0・/printfCI11D;p二First;/・移动指针从头指针开始・/while(sttemp(p->no,s)&&p!二NULL)/・查找结点确定插入位置*/p=p->next;/・指针后移,继续查找・/if(p==NULL)/・如p为空・/if(pニニFirst)/・如p为头指针,说明链表为空・/(First二info;/・新结点为头指针・/First->prior=NULL;/・头结点的前驱为空・/Last二First;/・唯一结点,尾指针等于头指针・/)else/・新结点插在尾部・/(Last->next二info;info->prior=Last;Last=info;/・尾指针指向新结点・/elseif(p==First)/*p不为空,但p为头指针,新结点插在第一个结点位置*/{infoー)prior=NULL;/・新结点的前驱为空・/info->next=p;/・新结点的后继为p*/p->prior=info;/*p的前驱是新结点・/First;info;/・修改头指针指向新结点・/}else/・新结点插入在中间某ー个位置p之前・/{info->next=p;/・新结点的后继是p*/infoー)prior=p->prior;/・新结点的前驱是p的前驱・/pー〉prior-〉next=info;/*p的前驱的后继是新结点・/pー〉prior二info;/*p的前驱是新结点・/)printf(* 302 303 304haveinserted%sSALARY 305”,info-〉name);printf(* 306Don'tforgetsave 307");/・提醒调用保存文件存盘・/}/・保存文件・/voidsave()(FILE*fp;/・定义指向文件的指针・/SALARY*p;/・定义移动指针・/charoutfile[10];/*保存输出文件名・/clrscr();/・清屏・/printf("Enteroutfilename,forexamplec:\\fl\\te.txt: 308");/・提示输入文件名格式信息・/ 309scanfI%s”,outfile);if((fp二fopen(outfile,"wb"))ニニNULL)/・为输出打开一个二进制文件・/(printf("cannotopenfile 310");return;/・返回・/)printf(* 311Savingfile 312");p二First;/・移动指针从头指针开始・/while(p!=NULL)/・如p不为空・/{fwrite(p,sizeof(SALARY),1,fp);/・写入一条记录・/p二p-〉next;/・指针后移,处理下一条记录・/)fclose(fp);/・关闭文件・/printf(*savesuccess!! 313〃);/・显示保存成功・//・读文件・/voidload()(SALARY*p,*q=NULL;/・定义记录指针变量・/FILE*fp:/・定义指向文件的指针・/charinfile[10];/・保存文件名・/clrscrO;/・清屏・/printf("Enterinfilename,forexamplec:\\fl\\te.txt: 314");/*输入文件名格式・/scanf("%s",infile);/・输入文件名・/if((fp=fopen(infile,"rb"))—NULL)/*打开一个二进制文件,为读方式・/{printf("cannotopenfile 315");/・如不能打开,则结束程序・/return;/・返回・/}while(First)/・当表不为空时,清空链表・/{p=First;/・从头指针开始・/First=First->next;/・删除头结点・/free(p);/・释放空间・/}printf(" 316Loadingfile! 317");/・显示正在读文件・/First=(SALARY*)malloc(sizeof(SALARY));/・为头指针申请空间・/if(!First)/・如果没有得到空间显示内存溢出・/(printf("outofmemory! 318");return;/・返回・/ 319}p=First;/・将头指针赋值给p*/while(!feof(fp))/・当文件不空时・/(if(l!=fread(p,sizeof(SALARY),1,fp))break;/・将记录读到p所指的结点・/p->next=(SALARY*)ma1loc(sizeof(SALARY));/・为p的后继申请空间・/if(!p->next)/・如果没有得到空间显示内存溢出・/(printf("outofmemory! 320");return;/・返回・/)p->prior=q;/・得到空间,则链接指针关系p的前驱为q*/q=p;/・保存P做为新的P结点的前驱・/p=p->next;/*p指针后移・/}q->next=NULL:/*q的后继为空・/Last=q;/・尾指针为q*/First->prior=NULL;/・头指针的前驱为空・/fclose(fp);/・关闭文件・/printf(*Youhavesuccessreaddatafromfile!!! 321");/・显示成功读入记录/*追加记录・/voidappend(){FILE*fp;/・定义指向文件的指针・/SALARY*info;/・指向追加信息的指针・/charinfiletlO];/・保存文件名・/floattemp;/・临时变量・/clrscrO;/・清屏・/gotoxy(1,3);printf("**************gongziguan11***********ネ);gotoxy(1,5);printf(*Iド);gotoxy(1,6);printf('|no|name|jbgz|");gotoxy(1,7);printf(*I11丨〃);info=(SALARY*)malloc(sizeof(SALARY));/・申请追加信息的空间・/if(!info)(printf(" 322outofmemory");/・没有空间,内存溢出・/exit(O);/*结束程序・/ 323}info->next=NULL;/・新信息的后继为空・/info->prior=NULL;/・新信息的前驱为空・/gotoxy(1,8);printf("I");gotoxy(12,8);printf("|");gotoxy(29,8);printf("|");gotoxy(38,8);printf("|");gotoxy(2,8);inputs(info->no,10);/・输入编号并校验・/gotoxy(13,8);inputs(info->name,14);/*输入姓名并校验・/gotoxy(30,8);scanf("%f",fitemp);/*输入基本工资・/infoー〉jbgz二temp;info->koukuan=0;/・扣款为0*/info->yfgz=0;/*应发エ资为〇・/info->shuijin=0;/・税金为0*/info->sfgz=0;/*实发エ资为〇・/printf(*|11丨”);printf(" 324 325 326Enterinfilename,forexamplec:\\fl\\te.txt: 327");/・提示输入文件名*/scanfinfile);if((fp=fopen(infile,*ab*))==NULL)/・打开文件・/(printf(z/cannotopenfile 328);return;/・返回・/}printf(* 329Appendingrecord! 330");if(l!=fwrite(info,sizeof(SALARY),1,fp))/・向文件中追加记录・/|printf("filewriteerror! 331〃);/・写函数返回值不为1,说明写入错误*/return;/・返回・/}printf(*appendsucess!! 332");/・显示追加成功・/fclose(fp);/・关闭文件・/}/・文件复制・/voidcopy()(charoutfile[10],infile[10];/・保存源文件名和目标文件名・/FILE*sfp,*tfp;/・定义指向源文件和目标文件的指针・/SALARY*p二NULL;/・定义临时指针,暂存读出的记录*/clrscr();printf〈Enterinfilename,forexamplec:\\fl\\te.txt: 333");scanf("版”,infile);/・输入源文件名・/ 334if((sfp=fopen(infile,"rb"))==NULL)/・二进制读方式打开源文件・/(printf("cannotopeninputfile 335");/・显示不能打开文件信息・/return;/・返回・/}printf("Enteroutfilename,forexamplec:\\fl\\te.txt: 336");/・提示输入目标文件名・/scanf("%s",outfile);/*输入目标文件名・/if((tfp二fopen(outfile,"wb"))==NULL)/・二进制写方式打开目标文件・/{printf("cannotopenoutputfile 337");return;}while(!feof(sfp))/・读文件直到文件尾・/(if(1!=fread(p,sizeof(SALARY),1,sfp))break;/*块读・/fwrite(p,sizeof(SALARY),1,tfp);/・块写・/fclose(sfp);/・关闭源文件・/fclose(tfp);/・关闭目标文件・/printf("youhavesuccesscopyfile!!! 338");/・显示成功拷贝・/}/・排序・/voidsort()(SALARY*p0,*p00,*pl,*pll,*p2;/・定义临时指针・/inti=l;/*统计当前排第几个结点・/clrscrO;/・清屏・/printf(* 339 340startsort.... 341");/・开始排序*/pl=pll=p2=First;while(pl!=NULL)/・当pl不为空时・/(pO=pl;/・待比较结点从pl开始・/p2=pl;/*p2从当前待排序位置开始・/while(p2->next!=NULL)/*p2的后继不为空时・/(if(p0->sfgz>p2->next->sfgz)/・找当前最小结点・/(p00=p2;/・找到当前最小结点记录其前驱指针・/p0=p2->next;/・记录当前最小值结点的指针pO*/)p2=p2->next;/・指针后移・/)Last=pO;/・当前最小结点为尾结点・/if(pl!=pO)/・判断最小结点是否是当前排序位置,不是则作指针修改・/(pOO->next=pO->next;/・将pOO的后继指向pO的后继・/pO->next->prior=pOO;/*p0的后继的前驱为pOO*/pO->next=pl;/*p0的后继指向下个排序位置pl*/pl->prior=pO;/*pl的前驱为pO*/if(i=l)(First=pO;/・作头指针・/First->prior=NULL;/・头指针的前驱为空・/)else/・不是第一个结点・/ 342Ipll->next=pO;/*pll的后继指向pO*/pO->prior=pll;/*p0的前驱指向pll*/pll=pl=pO;/・因pO是排好序的最后一个结点,pl是下ー个将要排序的位置,所以将pO赋值给pl和pll*/)i++;/・排好序的结点数加1*/pl=pl->neKt;/*pl后移指向下ー个待排序位置・/}printf("sortsucess!!! 343");/・输出排序成功・/)/・索引・/voidindex(){SALARY*p,*q,*t,*hl;/・定义临时指针・/clrscr();/・清屏・/printfC 344 345startindex 346 347");/・显示开始索引・/hl=First->next;/・将原表的头指针所指的下ー个结点作头指针・/First-〉next=NULL;/*第一个结点为新表的头结点・/Last=First;/・尾指针等于头指针・/while(hl!=NULL)/・当原表不为空时,进行排序・/(t=hl;/・取原表的头结点*/hl=hl->next;/*原表头结点指针后移・/p=First;/・设定移动指针p,从头指针开始・/q=First;/・设定移动指针q做为p的前驱,初值为头指针・/while(strcmp(t->no,p->no)>0&&p!=NULL)/・作编号比较・/(q=P;/・待排序点值大,应往后插,所以新表指针后移・/p=p->next;)if(p==q)/*p二q,说明待排序点值小,应排在首位・/(t->next=p;/・待排序点的后继为p*/p->prior=t;/*p的前驱结点指向待排序结点・/First=t;/・新头结点为待排序点・/First->prior=NULL;/・头指针的前驱为空・/}else/・待排序点应插入在屮间某个位置q和p之间,如p为空则是尾部・/(t->next-p;/*t的后继是p*/t->prior=q;/*t的前驱是q*/q->next=t;/*q的后继是t*/ 348if(p-NULL)/・判p是否为空・/Last=t;/・将t赋值为尾指针・/elsepー〉prior=t;/・否则将t赋值给p的前驱・/printf("indexsucess!!!\rT);/*索引排序成功*/}/・分类合计・/voidtotal()(structtl/・定义结构体保存合计数据・/{charu[7];/・部门・/floats;/・合计实发エ资・/}unit[20];/*定义ー个单位部门数不超过20个・/SALARY*p,*q;/・定义临时指针变量・/charsno[7],qno[7],*ptr;/*保存部门号・/floatsi;/・保存合计值・/inti,j;/・控制变量・/p=First;/・从指针开始・/i二〇;/・统计部门数・/clrscr();/・清屏求/while(p!=PWLL)/・当p不为空时做下面的处理・/(memcpy(sno,p->no,6);/・从编号中取出部门号*/sno[6]='、〇';/・做字符串结束标记・/q=p->next;/・将指针指向待比较的记录・/si=p->sfgz;/・当前部门的实发エ资初值作为该部门合计值的初值・/while(q!=NULL)/・内循环开始・/(memcpy(qno,q->no,6);/・读部门号・/qno[6]二‘、〇';/・做字符串结束标记*/if(strcmp(qno,sno)==0)/・比较部门号・/(sl+=q->sfgz;/・累加实发エ资・/q=q->next;/・指针指向下一条记录・/)elsebreak;/・不是一个部门的结束本次内循环・/}strcpy(unit[i].u,sno);/・将部门号写入部门结构体数组中・/unit[i].s=sl;/*将实发エ资写入部门结构体数组中・/i++;/*部门数累加・/if(qニニNULL)/・如果q为空,跳出循环・/ 349break;elseP=q;/・否则,将q赋值给p*/printf(" 350 351**************Totaltable************** 352");/*输出合计标题*/printf(〃、n-nounittotal 353〃);/*输出序号、部门、合计字段标题・/for(j=0;j 354*,j,unit[j].u,unit[j].s);/・输出合计值・/printf〈、n〃);
此文档下载收益归作者所有