c语言程序实习计划书Word格式.docx
《c语言程序实习计划书Word格式.docx》由会员分享,可在线阅读,更多相关《c语言程序实习计划书Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
('
、'
)'
;
⑵输出的形式:
运算结果,例如Answeris:
14;
⑶程序所能达到的功能:
对算术表达式求值并输出结果。
4.1需求分析
1、程序所能达到的功能:
能够处理以字符序列的形式输入的不含变量的实数表达式,正确处理负数与小数,判断表达式是还语法正确(包含分母不能为零的情况),正确实现对算术四则混合运算表达式的求值,能够将计算中遇到的问题和结果以文件的形式予以存储。
2、输入的形式和输入值的范围:
以字符串的形式输入表达式,以“#”结束。
3、输出的形式:
在计算过程中遇到的问题或最终的答案将显示在屏幕上,同时所计算的表达式的最终的结果也将保存在文件中。
4、测试数据:
输入“3*(7-2)#”时,输出“15.000000”,测试正确;
输入“!
(9-2)#”时,输出“输入错误!
”,测试正确。
4.2总体设计
4.2.1抽象数据类型定义
ADTStack{
数据对象:
D={
|
∈ElemSet,i=1,2,…,n,n≧0}
R1={<
>
|
i=2,…,n}
约定
端为栈顶,
端为栈底。
基本操作:
InitStack(&
S)
操作结果:
构造一个空栈S。
GetTop(S)
初始条件:
栈S已存在。
用P返回S的栈顶元素。
Push(&
S,ch)
插入元素ch为新的栈顶元素。
Pop(&
删除S的栈顶元素。
In(ch)
判断字符是否是运算符,运算符即返回1。
Precede(c1,c2)
c1,c2为运算符。
判断运算符优先权,返回优先权高的。
Operate(a,op,b)
a,b为整数,op为运算符。
a与b进行运算,op为运算符,返回其值。
num(n)
返回操作数的长度。
EvalExpr()
输入表达式合法。
返回表达式的最终结果。
}ADTStack
4.2.2函数模块说明
为实现算符优先算法,可以使用两个工作栈。
一个称做OPTR,用以寄存运算符;
另一个称做OPND,用以寄存操作数或运算结果。
算法的基本思想是:
(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈底元素
(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。
4.2.3主函数流程图
4.2.4函数模块调用关系
4.2.5运算符间的优先关系
θ1θ2
+
-
*
/
(
)
#
<
=
4.3详细设计
4.3.1数据类型的定义及基本操作
//=====ADTStack的表示与实现=====
//-----栈的顺序存储表示-----
#defineSTACK_INIT_SIZT100;
#defineSTACKINCREMENT10
typedefstruct{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
//-----基本操作的算法描述-----
StatusInitStack(SqStack&
S){
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}
StatusGetTop(SqStackS,SElemType&
e){
if(S.top==S.base)returnERROR;
e=*(S.top-1);
StatusPush(SqStack&
S,SElemTypee){
if(S.top-S.base>
=S.stacksize){
S.base=(SElemType*)realloc(S.base
(S.StackSize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
*S.top++=e;
StatusPop(SqStack&
S,SElemType&
e=*--S.top;
OperandTypeEvaluateExpession(){
InitStack(OPTR);
Push(OPTR,’#’);
InitStack(OPND);
c=getchar();
while(c!
’#’||GetTop(OPTR)!
=’#’){
In(c,OP)){Push((OPND,c);
else
switch(Precede(GetTop(OPTR),c)){
case’<
’:
Push(OPTR,c);
break;
case’=’:
Pop(OPTR,x);
case’>
Pop(OPTR,theta);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
}
4.3.2函数调用关系
4.3.3主要模块的算法描述
voidmain(){
SqStack_TOPTR;
SqStack_NOPND;
floata,b,i;
chartheta,c,x;
InitStack_T(&
OPTR);
Push_T(&
OPTR,’#’);
InitStack_N(&
OPND);
printf(“请输入表达式关以’#’结尾:
\n”);
c=getchar();
if(c==35||(c>
=40&
&
c<
=43)||c==45||(c>
=47&
=57))
{
=’#’||GetTop_T(&
OPTR)!
=’#’)
if(c>
=48&
=57)
{
i=(float)c-48;
Push_N(&
OPND,i);
c=getchar();
switch(Precede(GetTop_T(&
OPND),c))
OPTR,c);
break;
x=Pop_T(&
theat=Pop_T(&
b=Pop_N(&
a=Pop_N(&
Push_N(&
OPND,Operate(a,theta,b));
printf(“结果是%f\n”,GetTop_N(&
OPND));
elseprintf(“输入错误!
4.4测试与分析
4.4.1测试
加法测试,输入正确,输出正确,测试正确:
乘法测试,输入正确,输出正确,测试正确:
输入表达式正确,输出正确,测试正确:
输入表达式错误,能正确判断,测试正确:
4.4.2分析
内容包括:
1、调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析:
遇到的问题:
调试过程中遇到了输入非法字符不输出“错误!
”的情况。
解决的办法:
查ASCII码表得知运算符’+’,’-‘,’*’,’/’,’(‘,’)’,’#’和运算数’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’相应的ASCII值。
在主程序中加入了判断语句,判断输入的是否为运算符或运算数。
如果是,则进行正常运算;
如果不是,则返回错误。
2、算法的时间复杂度和空间复杂度的分析:
中缀表达式运算时间主要用在字符串扫描和算符优先权的比较上。
把#看作运算符,操作数与运算符个数相同,最坏情况下优先级比较是n/2次,即运算顺序完全是逆序的,每个字符扫描一遍是O(n)的,所以整个算法复杂度是O(n2)的。
算法中用到两个栈,分别为O(n/2),其算法空间复杂度是O(n)。
4.5附录
源程序
#include"
stdio.h"
stdlib.h"
#defineOK1
#defineERROR0
#defineOVERFLOW0
#defineSTACK_INIT_SIZE100
char*base;
char*top;
intstacksize;
}SqStack_T;
float*base;
float*top;
}SqStack_N;
voidInitStack_T(SqStack_T*S){
(*S).base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
(*S).base)exit(OVERFLOW);
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
voidInitStack_N(SqStack_N*S){
(*S).base=(float*)malloc(STACK_INIT_SIZE*sizeof(float));
charGetTop_T(SqStack_T*S){
chare;
if((*S).top==(*S).base)returnERROR;
e=*((*S).top-1);
returne;
floatGetTop_N(SqStack_N*S){
floate;
charPush_T(SqStack_T*S,chare){
if((*S).top-(*S).base>
=(*S).stacksize){
(*S).base=(char
*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(char));
if(!
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
*((*S).top)++=e;
returnOK;
floatPush_N(SqStack_N*S,floate){
(*S).base=(float
*)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(float));
charPop_T(SqStack_T*S){
e=*(--(*S).top);
floatPop_N(SqStack_N*S){
charm[7]="
+-*/()#"
;
charn[7][7]={"
"
"
="
>
="
};
charPrecede(chara,charb){
inti=0,j=0;
while(m[i]!
=a)
i++;
while(m[j]!
=b)
j++;
return(n[i][j]);
floatOperate(floata,chartheta,floatb){
floatr;
switch(theta){
case'
:
r=a+b;
r=a-b;
r=a*b;
if(b!
=0)r=a/b;
elseprintf("
输入错误!
);
break;
returnr;
SqStack_TOPTR;
SqStack_NOPND;
floata,b,i;
InitStack_T(&
OPTR,'
#'
InitStack_N(&
printf("
请输入表达式并以'
结尾:
\n"
c=getchar();
if(c==35||(c>
while(c!
='
||GetTop_T(&
{
if(c>
{
i=(float)c-48;
Push_N(&
c=getchar();
}
else
switch(Precede(GetTop_T(&
OPTR),c))
{
case'
'
theta=Pop_T(&
}
}
}printf("
结果是%f\n"
GetTop_N(&
elseprintf("
5总结与展望
通过这段时间的课程设计,本人对计算机的应用、数据结构的作用以及C语言的使用都有了更深的了解。
当然也遇到不少问题,也正是国为这些问题引发的思考给我带来了收获。
从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不知从何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变。
我发现无论是专业知识还是动手能力,自己都有很大程度的提高。
在实际上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,为后续课程的学习及实践打下良好的基础。
这次课程设计让我更加了解大一学到的C和这个学期学到的数据结构的紧密联系。
设计题目不仅要求设计者对课本知识有较深刻的了解,同时要有较强的思维动手能力。
这次的课程设计让我有一个深刻的体会:
严谨!
编程最需要的就是严谨,往往检查到的错误是在某个括号、分号、引号等不应该犯错的地方上。
程序设计时难免遇到错误,但这不是坏事情,它可以让我发现自己的薄弱环节,在具体操作中还可以巩固所学的C及数据结构。
更加体会到了C的语句简洁、使用灵活、执行效率高等特点。