《课程设计.doc》由会员分享,可在线阅读,更多相关《课程设计.doc(12页珍藏版)》请在三一办公上搜索。
1、一、需求分析设C语言程序代码中包含如下符号/* */,(), ,编写程序检测一段C代码中上述符号是否正确。二、 概要设计利用栈的特点,来进行符号匹配,程序所涉及的数据类型如下:1、抽象数据类型栈的定义如下:ADT Stack数据对象D=ai | ai属于ElemSet, i=1,2,n, n=0数据关系R1: | ai-1,ai属于D,i=2,n约定an端为栈顶,a1端为栈底。基本操作:Initstack(&S)操作结果:构造一个空栈SClearstack(&S)初始条件:栈S已存在。操作结果:将S清为空栈。Stackempty(S)初始条件:栈S已存在。操作结果:若栈S为空栈,则返回TRUE
2、,否则返回FALSE。Push(&S,e) 初始条件:栈S已存在。 操作结果:插入元素e为新的栈顶元素。Pop(&S,&e)初始条件:栈S已存在且非空。操作结果:删除栈顶元素,并用e返回其值。2、程序分为三个模快1) 主程序模块,主函数为:int main( ) 定义栈,构建空栈 定义输入信息为char型 给定一个n值,利用while循环实现多次调用 While(n-) 输入所要检测的C语言代码调用符号匹配match函数 判定程序结果,并输出结果2) 关于要用到栈的模块设计实现栈的各种操作3) 关于符号匹配的函数设计实现程序要求的符号匹配三、 详细设计1) 栈的设计部分 #define STA
3、CK_INIT_SIZE 100 /存储空间初始分配量#define STACKINCREMENT 10 /存储空间分配增量 typedef struct selemtype *base; /在栈构造之前和销毁之后,base为空selemtype *top; /栈顶指针int stacksize; /当前已分配的存储空间,以元素为单位sqstack;2) 关于栈的函数设计部分Status initstack(sqstack &s) /*构造一个空栈*/Status Clearstack(sqstack &s) /*清空栈操作*/Status push(sqstack &s,selemtype
4、e) /*增添新的栈顶元素*/Status pop(sqstack &s,char &e) /* 删除现有栈顶元素*/Status stackempty(sqstack s) /*判断栈是否为空*/3) 匹配函数设计部分 void match(sqstack &s)char str,e;int flag=1,T; /flag=1标志着当前栈中无“/*”符号 /T为真时代表进行Pop操作前栈不为空str=getchar();F=1; / 标志着没有出现过匹配不成功的情况,设为全局变量while(str!=EOF) /输入代码直到输入EOF才停止输入switch(str) case*:if(fla
5、g=0) /flag=0标志栈中有“/*”符号str=getchar();/当输入的字符为*时,就看下一个字符是否为/if(str=/)str=getchar();T=pop(s,e);T=pop(s,e);flag=1;flag1=1; /如果是/,则对栈S做两次消除栈顶元素操作/flag=1标志着当前栈中无“/*”符号,flag1=1标志匹配成功elsestr=getchar();flag1=0;break;case /:if(flag=1) /当前栈中无“/*”符号时,判断下一个字符str=getchar();if(str=*) /字符为*,就将这两字符依次进栈,并改flag的值为0st
6、r=getchar();push(s,/);push(s,*);flag=0; /flag=0标志栈中有“/*”符号else str=getchar();flag1=0; /否则都不进栈,继续往下输break;case (:if(flag=1)push(s,();str=getchar();break; /(进栈case :if(flag=1)push(s,);str=getchar();break; /进栈case :if(flag=1)push(s,);str=getchar();break; /进栈case):if(flag=1) /栈S中没有注释符号左边时,才进行后面操作T=pop(s
7、,e); /将栈顶元素Pop出来,进行匹配判断if(e=()flag1=1;str=getchar();break;else flag1=0;F=0;str=getchar();break;elsestr=getchar();break;case:if(flag=1) /栈S中没有注释符号左边时,才进行后面操作T=pop(s,e); /将栈顶元素Pop出来,进行匹配判断if(e=)flag1=1;str=getchar();break;else flag1=0;F=0;str=getchar();break;elsestr=getchar();break;case:if(flag=1) /栈S
8、中没有注释符号左边时,才进行后面操作T=pop(s,e); /将栈顶元素Pop出来,进行匹配判断if(e=)flag1=1;str=getchar();break;else flag1=0;F=0;str=getchar();break;elsestr=getchar();break;default:str=getchar();break;if(flag=1&flag1=1&stackempty(s)&T)flag1=1;/防止匹配字符只出现一半else flag1=0;Clearstack(s); /防止检查完的代码结果影响下一次检测 四、 调试分析1. 刚开始我抽到的题,并不是这道题,老师
9、说多项式的运算讲的不多,让我换题,本来想,这后面的题肯定很难的,我当时看到这个题的时候没想很多,想想这题的要求并不是很复杂,就报上去了。谁知道编起来,考虑的条件真的好复杂。2. 对于这个题,单括号的匹配并不是很困难的,难的是注释符号/* */的匹配,我们要解决的是双字符符号匹配,这样就会有很多情况出现,而且要注意的是注释符号左边部分一旦出现,那么在找到右边之前,所遇到的字符都是不能入栈的,即注释符号之间的字符对C语言程序而言没有任何作用。3. 程序难点之二在于,标志变量设的多,因为程序可能出现的情况很多。至于会出现的多种情况的考量,我在详细设计部分,match函数解释标识变量有涉及,可能我的考
10、虑还有很多不足,希望老师能指导一二,让我的程序完美一些。五、 用户使用说明 该程序使用很简单:l 你想测试多少次,就将程序中的n赋值为多少。进入调试界面时,直接会提示你输入测试代码。l 直接输入你要测试的代码,输完之后直接按回车,在按ctrl键+Z结束输入,再按回车键,即出现结果。l 直接又进入下一个代码检测,重复上面两操作。六、 测试结果 这个程序测试代码主要是测试符号匹配:l n=1请输入测试的代码:() EOF这段代码是正确的l n=5请输入测试的代码 () EOF 这段代码是错误的bdsj gfrewfbdnsgbfyerwb/*jbhgey*/ EOF这段代码是正确的bdsj gfr
11、ewfbdnsgbfyerwb/*jbhgey*/ EOF 这段代码是正确的dvhytr/*dsjgfyexbh fjsjfgyugf EOF 这段代码是错误的Sbjadgefgvb()*/ EOF 这段代码是错误的Press any key to continue 这个程序对于这四种符号来说,只要出现不匹配的情况就会报错七、 附录#include #include#define ERROR 0#define OVERFLOW -2#define OK 1typedef char selemtype;typedef int Status;#define STACK_INIT_SIZE 100
12、/存储空间初始分配量#define STACKINCREMENT 10 /存储空间分配增量int flag1=0,F=1; /全局变量typedef struct selemtype *base; /在栈构造之前和销毁之后,base的值为空selemtype *top; /栈顶指针int stacksize; /当前已分配的存储空间,以元素为单位sqstack;Status initstack(sqstack &s) /*构造一个空栈*/ s.base =(selemtype *)malloc(STACK_INIT_SIZE*sizeof(selemtype);if(!s.base)exit(
13、OVERFLOW);s.top=s.base;s.stacksize=STACK_INIT_SIZE;return OK;Status Clearstack(sqstack &s) /*清空栈操作*/if(!s.base)exit(OVERFLOW);s.top=s.base;return OK;Status push(sqstack &s,selemtype e) /*往栈内添加元素,增添新的栈顶元素*/if(s.top-s.base=s.stacksize)s.base=(selemtype *)realloc(s.base,(s.stacksize+STACKINCREMENT)*siz
14、eof(selemtype);if(!s.base) exit(OVERFLOW);s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;*s.top+ =e;return OK;Status pop(sqstack &s,char &e) /* 删除现有栈顶元素,并用e返回其值*/if(s.top = s.base) return ERROR;e= *( -s.top);return OK;Status stackempty(sqstack s) /*判断栈是否为空*/if(s.top=s.base)return OK;elsereturn
15、 ERROR;void match(sqstack &s)char str,e;int flag=1,T; /flag=1标志着当前栈中无“/*”符号 /T为真时代表进行Pop操作前栈不为空str=getchar();F=1; / 标志着没有出现过匹配不成功的情况,设为全局变量while(str!=EOF) /输入代码知道输入EOF才停止输入switch(str) case*:if(flag=0) /flag=0标志栈中有“/*”符号str=getchar();/当输入的字符为*时,就看下一个字符是否为/if(str=/)str=getchar();T=pop(s,e);T=pop(s,e);
16、flag=1;flag1=1; /如果是/,则对栈S做两次消除栈顶元素操作/flag=1标志着当前栈中无“/*”符号,flag1=1标志匹配成功elsestr=getchar();flag1=0;break;case /:if(flag=1) /当前栈中无“/*”符号时,判断下一个字符str=getchar();if(str=*) /字符为*,就将这两字符依次进栈,并改flag的值为0str=getchar();push(s,/);push(s,*);flag=0; /flag=0标志栈中有“/*”符号else str=getchar();flag1=0; /否则都不进栈,继续往下输break
17、;case (:if(flag=1)push(s,();str=getchar();break; /(进栈case :if(flag=1)push(s,);str=getchar();break; /进栈case :if(flag=1)push(s,);str=getchar();break; /进栈case):if(flag=1) /栈S中没有注释符号左边时,才进行后面操作T=pop(s,e); /将栈顶元素Pop出来,进行匹配判断if(e=()flag1=1;str=getchar();break;else flag1=0;F=0;str=getchar();break;elsestr=g
18、etchar();break;case:if(flag=1) /栈S中没有注释符号左边时,才进行后面操作T=pop(s,e); /将栈顶元素Pop出来,进行匹配判断if(e=)flag1=1;str=getchar();break;else flag1=0;F=0;str=getchar();break;elsestr=getchar();break;case:if(flag=1) /栈S中没有注释符号左边时,才进行后面操作T=pop(s,e); /将栈顶元素Pop出来,进行匹配判断if(e=)flag1=1;str=getchar();break;else flag1=0;F=0;str=g
19、etchar();break;elsestr=getchar();break;default:str=getchar();break;if(flag=1&flag1=1&stackempty(s)&T)flag1=1;/防止匹配字符只出现一半else flag1=0;Clearstack(s); /防止检查完的代码结果影响下一次检测int main()sqstack s;initstack(s);char str;int n; /循环次数 printf(“%d”,&n);while(n-)printf(请输入测试的代码:n);match(s);if(F=1)if(flag1 &stackempty(s) )printf(这段代码是正确n);elseprintf(这段代码是错误的n);elseprintf(这段代码是错误的n);return 0;