一个调试过程中的错误,请各位热心鱼油看一下
本帖最后由 Luker 于 2018-12-24 18:34 编辑#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define STACKINCREMENT 10 //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'
typedef char ElemType;
typedef struct //栈的结构体
{
ElemType *bottom; //栈底指针
ElemType *top; //栈顶指针
int stackSize; //栈的大小
}sqStack;
void InitStack(sqStack *s); //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s,ElemType e); //入栈
void Pop(sqStack *s,ElemType *e); //出栈
int StackLen(sqStack *s); //返回栈的当前容量
void Cleanup(sqStack *s); //清空栈
int main(void)
{
sqStack s;
ElemType end,c,e;
int first,second;
printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
scanf("%c",&c);
while(c!='\n') //判断输入是否为结束计算的标识
{
if(c==addition || c==division || c==subtraction ||c==multiplication) //当输入为这四个运算符中的其中一个时
{
Pop(&s,&e); //出栈并将其值赋给second
second=e-'0';
Pop(&s,&e); //出栈并将其值赋给first
first=e-'0';
if(c==addition) //加法运算
{
end=first+second+48;
}
if(c==division) //除法运算
{
end=first/second+48;
}
if(c==subtraction) //减法运算
{
end=first-second+48;
}
if(c==multiplication) //乘法运算
{
end=first*second+48;
}
Push(&s,end); //将运算的结果压入栈中
}
else
{
Push(&s,c); //压栈
}
scanf("%c",&c); //获取下一个输入
}
Pop(&s,&e); //出栈
printf("计算结果:%d",e-'0'); //显示最后的结果
Cleanup(&s); //清空栈
return 0;
}
void InitStack(sqStack *s)
{
s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
if(!s->bottom) //申请失败时
{
exit(0);
}
s->top=s->bottom;
s->stackSize=STACKINCREMENT;
}
void Push(sqStack *s,ElemType e)
{
if(s->top-s->bottom>=s->stackSize) //若栈已满
{
s->bottom=(ElemType *)realloc(s->bottom,(s->stackSize+STACKINCREMENT)*sizeof(ElemType)); //增加栈的容量
if(!s->bottom) //申请失败时
{
exit(0);
}
}
*(++s->top)=e;
}
void Pop(sqStack *s,ElemType *e)
{
if(s->top==s->bottom) //栈为空时
{
exit(0);
}
*e=*s->top;
s->top--;
}
int StackLen(sqStack *s)
{
return (s->top-s->bottom);
}
void Cleanup(sqStack *s)
{
int LEN=s->stackSize;
int i;
for(i=0;i<LEN;i++)
{
free(s->bottom);
s->bottom++;
}
s->bottom=s->top=NULL;
s->stackSize=0;
}
一个通过栈实现的逆波兰计算器,调试过程跳出这个弹窗,请问是什么意思?{:10_291:} 楼主您好 。 这种问题一般都是指针越界访问了系统区造成的。 楼主可以放一下问题代码段。一起分析一下。 小酒酒呢 发表于 2018-12-24 08:03
楼主您好 。 这种问题一般都是指针越界访问了系统区造成的。 楼主可以放一下问题代码段。一起分析一下。
哥们,代码贴上去了,请你帮我看看,多谢{:10_254:} Luker 发表于 2018-12-24 18:35
哥们,代码贴上去了,请你帮我看看,多谢
不知楼主的问题急不急 我现在身边没有电脑可不可以明天帮您看看。 小酒酒呢 发表于 2018-12-24 23:21
不知楼主的问题急不急 我现在身边没有电脑可不可以明天帮您看看。
不急,你肯帮我看已是万分感激,多谢{:10_287:} 小酒酒呢 发表于 2018-12-24 23:21
不知楼主的问题急不急 我现在身边没有电脑可不可以明天帮您看看。
哥们,你不会是忘了吧{:5_96:} Luker 发表于 2018-12-27 00:16
哥们,你不会是忘了吧
不好意思不好意思我们最近突然做课程设计。有一丢丢忙,放心小哥哥,你先自己分析分析,我一定抽时间给你满意回复 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define STACKINCREMENT 10 //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'
typedef char ElemType;
typedef struct //栈的结构体
{
ElemType *bottom; //栈底指针
ElemType *top; //栈顶指针
int stackSize; //栈的大小
}sqStack;
void InitStack(sqStack *s); //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s, ElemType e); //入栈
void Pop(sqStack *s, ElemType *e); //出栈
int StackLen(sqStack *s); //返回栈的当前容量
void Cleanup(sqStack *s); //清空栈
int main(void)
{
sqStack s;
InitStack(&s); // 这里
ElemType end, c, e;
int first, second;
printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
scanf("%c", &c);
while(c != '\n') //判断输入是否为结束计算的标识
{
if(c == addition || c == division || c == subtraction || c == multiplication) //当输入为这四个运算符中的其中一个时
{
Pop(&s, &e); //出栈并将其值赋给second
second = e - '0';
Pop(&s, &e); //出栈并将其值赋给first
first = e - '0';
if(c == addition) //加法运算
{
end = first + second + 48;
}
if(c == division) //除法运算
{
end = first / second + 48;
}
if(c == subtraction) //减法运算
{
end = first - second + 48;
}
if(c == multiplication) //乘法运算
{
end = first * second + 48;
}
Push(&s, end); //将运算的结果压入栈中
}
else
{
Push(&s, c); //压栈
}
scanf("%c", &c); //获取下一个输入
}
Pop(&s, &e); //出栈
printf("计算结果:%d", e - '0'); //显示最后的结果
// 这个函数存在逻辑问题,自己好好想一想为什么
//Cleanup(&s); //清空栈
return 0;
}
void InitStack(sqStack *s)
{
s->bottom = (ElemType *)malloc(STACKINCREMENT * sizeof(ElemType));
if(!s->bottom) //申请失败时
{
exit(0);
}
s->top = s->bottom;
s->stackSize = STACKINCREMENT;
}
void Push(sqStack *s, ElemType e)
{
if(s->top - s->bottom >= s->stackSize) //若栈已满
{
s->bottom = (ElemType *)realloc(s->bottom, (s->stackSize + STACKINCREMENT) * sizeof(ElemType)); //增加栈的容量
if(!s->bottom) //申请失败时
{
exit(0);
}
}
*(++s->top) = e;
}
void Pop(sqStack *s, ElemType *e)
{
if(s->top == s->bottom) //栈为空时
{
exit(0);
}
*e = *s->top;
s->top--;
}
int StackLen(sqStack *s)
{
return (s->top - s->bottom);
}
/* 这个函数不对
void Cleanup(sqStack *s)
{
int LEN = s->stackSize;
int i;
for(i = 0; i<LEN; i++)
{
free(s->bottom);
s->bottom++;
}
s->bottom = s->top = NULL;
s->stackSize = 0;
}*/ 哇、、被楼上的小哥哥抢先了{:10_266:}。我还是要说一下,其实问题看似复杂,其实都出在粗心上。使用栈并没有初始化。全篇的出栈入栈,都没有对 stacksize 更新。楼上给你留了问题,那么我也就不点破了,免得浪费楼上苦心。楼主自己思考下吧,以后细心一些就好了,尤其在对于这些指针的处理上。 人造人 发表于 2018-12-27 12:39
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define STACKINCREMENT 10 //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'
typedef char ElemType;
typedef struct //栈的结构体
{
ElemType *bottom; //栈底指针
ElemType *top; //栈顶指针
int stackSize; //栈的大小
}sqStack;
void InitStack(sqStack *s); //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s,ElemType e); //入栈
void Pop(sqStack *s,ElemType *e); //出栈
int StackLen(sqStack *s); //返回栈的当前容量
void Cleanup(sqStack *s); //清空栈
int main(void)
{
sqStack s;
InitStack(&s);
ElemType end,c,e;
int first,second;
printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
scanf("%c",&c);
while(c!='\n') //判断输入是否为结束计算的标识
{
if(c==addition || c==division || c==subtraction ||c==multiplication) //当输入为这四个运算符中的其中一个时
{
Pop(&s,&e); //出栈并将其值赋给second
second=e-'0';
Pop(&s,&e); //出栈并将其值赋给first
first=e-'0';
if(c==addition) //加法运算
{
end=first+second+48;
}
if(c==division) //除法运算
{
end=first/second+48;
}
if(c==subtraction) //减法运算
{
end=first-second+48;
}
if(c==multiplication) //乘法运算
{
end=first*second+48;
}
Push(&s,end); //将运算的结果压入栈中
}
else
{
Push(&s,c); //压栈
}
scanf("%c",&c); //获取下一个输入
}
Pop(&s,&e); //出栈
printf("计算结果:%d",e-'0'); //显示最后的结果
Cleanup(&s); //清空栈
return 0;
}
void InitStack(sqStack *s)
{
s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
if(!s->bottom) //申请失败时
{
exit(0);
}
s->top=s->bottom;
s->stackSize=STACKINCREMENT;
}
void Push(sqStack *s,ElemType e)
{
if(s->top-s->bottom>=s->stackSize) //若栈已满
{
s->bottom=(ElemType *)realloc(s->bottom,(s->stackSize+STACKINCREMENT)*sizeof(ElemType)); //增加栈的容量
if(!s->bottom) //申请失败时
{
exit(0);
}
}
*(++s->top)=e;
}
void Pop(sqStack *s,ElemType *e)
{
if(s->top==s->bottom) //栈为空时
{
exit(0);
}
*e=*s->top;
s->top--;
}
int StackLen(sqStack *s)
{
return (s->top-s->bottom);
}
void Cleanup(sqStack *s)
{
int LEN=StackLen(s);
ElemType *temp,*head;
head=s->bottom;
s->bottom++;
int i;
for(i=0;i<LEN;i++)
{
temp=s->bottom;
s->bottom++;
free(temp);
}
head=s->top=NULL;
s->stackSize=0;
}
DL,你看现在可以了吗?对于你的帮助万分感激 小酒酒呢 发表于 2018-12-27 17:16
哇、、被楼上的小哥哥抢先了。我还是要说一下,其实问题看似复杂,其实都出在粗心上。使用栈并没 ...
多谢哥们,我老是要犯这种低级的错误,唉,还是练得不够,我这里的stacksize是整个栈的最大容量,一般不变,我里面已经用stackLen函数来获取这个栈的当前容量了,不知道这样理解对不对,还望赐教{:5_108:} Luker 发表于 2018-12-27 21:31
多谢哥们,我老是要犯这种低级的错误,唉,还是练得不够,我这里的stacksize是整个栈的最大容量,一般不 ...
从严蔚敏教材角度看,stacksize应该是当前栈中使用的元素,初始化为0。而设一个最大栈的容量,这个为固定不变的。然后就是建议楼主找找malloc和free函数的关系,看看free的释放是释放那些空间,以免之后还会出现问题。还是学习造人大佬,给大家留思考余地{:10_334:} Luker 发表于 2018-12-27 21:27
#include
#include
#include
不可以
Clean和Destroy是不一样的
一个malloc对应一个free,且只能对应一个
void InitStack(sqStack *s)
{
s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
if(!s->bottom) //申请失败时
{
exit(0);
}
s->top=s->bottom;
s->stackSize=STACKINCREMENT;
}
void Cleanup(sqStack *s)
{
int LEN=StackLen(s);
ElemType *temp,*head;
head=s->bottom;
s->bottom++;
int i;
for(i=0;i<LEN;i++)
{
temp=s->bottom;
s->bottom++;
free(temp);
}
head=s->top=NULL;
s->stackSize=0;
} malloc了一次
free了LEN次
小甲鱼的数据结构与算法里是这么讲的{:10_262:} 人造人 发表于 2018-12-27 23:06
malloc了一次
free了LEN次
被小甲鱼的数据结构与算法的教程坑了{:5_96:} Luker 发表于 2018-12-27 23:17
被小甲鱼的数据结构与算法的教程坑了
贴一下视频链接
人造人 发表于 2018-12-27 23:21
贴一下视频链接
https://www.bilibili.com/video/av29175690/?p=2
在栈的那几节就有提到栈的清除,他就是这么讲的 @小甲鱼
我好像记得很久之前我就已经提过这个问题了
页:
[1]