在 Stack Top 上推送任何超过 127 的数字后代码停止工作
Code stops working after pushing any number over 127 on Stack Top
C 语言程序!
为了我的家庭作业,我必须编写一个程序,使用 ADT Stack 查找前缀中给定的算术表达式的值。输入是一个字符串,例如'- + 5 12 * 7 3',输出将是'-4'。
我解决了作业,我认为一切正常。但出于某种原因,当我将数字压入堆栈顶部时,如果该数字大于或等于 128,或小于或等于 -128,则一旦压入堆栈,该数字就会完全改变。比如我把129压入栈中,当我从栈顶取数的时候,已经变成了-127.
该程序有超过 150 行代码,所以我不知道如果我 post 在这里编辑它会有多大帮助,我只是想知道是否有人知道为什么会这样。
(这里是我的程序的简要思路:输入是一个字符串,其中数字和运算符用空格分隔。
计算中缀的程序是这样的:从字符串末尾的字符开始,从尾到头。如果 char 是数字,首先找到整数(直到空白)然后将其压入堆栈(作为 int,而不是 char)。如果 char 是运算符,则从堆栈中删除最后两个数字并对它们执行操作,然后将其压回堆栈。堆栈中的最后一个数字是结果。
我知道这真的很模糊,所以如果整个程序能提供更多帮助,我会post。所有的操作都是正确的,我检查了一下,具体是我把它们放到stack上就出问题了。另外,我使用指针实现了字符串。)
编辑:我将输出改为“-4”,而不是“4”。我的错!
编辑:代码:(另外,我使用 int 作为我的数据类型。)
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct _element{
int c;
struct _element *next;
}element;
typedef element *stack;
void StMakeNull(stack *Sp){
*Sp=NULL;
}
int StEmpty(stack S){
if(S==NULL) return 1;
else return 0;
}
void StPush(stack *Sp, char d){
element *temp;
temp=(*Sp);
(*Sp)=(element*)malloc(sizeof(element));
(*Sp)->c=d;
(*Sp)->next=temp;
}
void StPop(stack *Sp){
if(StEmpty(*Sp)) exit(202);
else{
element *temp;
temp=(*Sp);
(*Sp)=(*Sp)->next;
free(temp);
}
}
char StTop(stack S){
if(StEmpty(S)) exit(202);
return S->c;
}
int Jel_broj(char c){
int d=c;
if(d>=48 && d<=57)
return 1;
return 0;
}
int Jel_operator(char c){
if(c=='+') return 1;
else if(c=='-') return 2;
else if(c=='*') return 3;
else if(c=='/') return 4;
else if(c=='^') return 5;
return 0;
}
int pot(int n, int k){
int l=1;
while(k>0){
l*=n;
k--;
}
return l;
}
void izracunaj(char* niz, int n){
int broj=0, pomocni, j, nn, b1, b2;
stack S;
StMakeNull(&S);
while(n>=0){
if(Jel_broj(niz[n])){
broj=0; j=0; nn=n;
while(Jel_broj(niz[nn])){
j++;
nn--;
}
nn=j;
while(Jel_broj(niz[n-j+1])){
pomocni=niz[n-j+1];
broj=broj*10+(pomocni-'0');
j--;
}
StPush(&S, broj);
n=n-nn+1;
}
else if(Jel_operator(niz[n])){
if(Jel_operator(niz[n])==1){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1+b2);
}
else if(Jel_operator(niz[n])==2){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1-b2);
}
else if(Jel_operator(niz[n])==3){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1*b2);
}
else if(Jel_operator(niz[n])==4){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1/b2);
}
else if(Jel_operator(niz[n])==5){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, pot(b1,b2));
}
}
n--;
}
printf("%d", StTop(S));
}
int main(){
char *niz=NULL;
int n=0;
char c;
while(1){
scanf("%c", &c);
if(c=='\n'){
niz=(char*)realloc(niz, (++n)*sizeof(char));
niz[n-1]='[=10=]';
break;
}
niz=(char*)realloc(niz, (++n)*sizeof(char));
niz[n-1]=c;
}
izracunaj(niz,n-2);
return 0;
}
规则说 post 代码片段是有充分理由的:不看代码就很难确定问题。以后,总是 post 要看的东西(并遵守代码片段的规则)。
但在这种情况下,即使没有它,我也能很好地猜测发生了什么:8 位类型的有符号溢出。您的堆栈使用 signed char
(或等效)数据类型,或者您正在某处强制转换为这样的值。可能是您使用的整数解析?
您可能将这些值存储为 int
,但是当您将它们放入和取出堆栈时,它们会被截断为 char
值。
void StPush(stack *Sp, char d)
char StTop(stack S)
C 语言程序!
为了我的家庭作业,我必须编写一个程序,使用 ADT Stack 查找前缀中给定的算术表达式的值。输入是一个字符串,例如'- + 5 12 * 7 3',输出将是'-4'。
我解决了作业,我认为一切正常。但出于某种原因,当我将数字压入堆栈顶部时,如果该数字大于或等于 128,或小于或等于 -128,则一旦压入堆栈,该数字就会完全改变。比如我把129压入栈中,当我从栈顶取数的时候,已经变成了-127.
该程序有超过 150 行代码,所以我不知道如果我 post 在这里编辑它会有多大帮助,我只是想知道是否有人知道为什么会这样。
(这里是我的程序的简要思路:输入是一个字符串,其中数字和运算符用空格分隔。
计算中缀的程序是这样的:从字符串末尾的字符开始,从尾到头。如果 char 是数字,首先找到整数(直到空白)然后将其压入堆栈(作为 int,而不是 char)。如果 char 是运算符,则从堆栈中删除最后两个数字并对它们执行操作,然后将其压回堆栈。堆栈中的最后一个数字是结果。
我知道这真的很模糊,所以如果整个程序能提供更多帮助,我会post。所有的操作都是正确的,我检查了一下,具体是我把它们放到stack上就出问题了。另外,我使用指针实现了字符串。)
编辑:我将输出改为“-4”,而不是“4”。我的错!
编辑:代码:(另外,我使用 int 作为我的数据类型。)
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct _element{
int c;
struct _element *next;
}element;
typedef element *stack;
void StMakeNull(stack *Sp){
*Sp=NULL;
}
int StEmpty(stack S){
if(S==NULL) return 1;
else return 0;
}
void StPush(stack *Sp, char d){
element *temp;
temp=(*Sp);
(*Sp)=(element*)malloc(sizeof(element));
(*Sp)->c=d;
(*Sp)->next=temp;
}
void StPop(stack *Sp){
if(StEmpty(*Sp)) exit(202);
else{
element *temp;
temp=(*Sp);
(*Sp)=(*Sp)->next;
free(temp);
}
}
char StTop(stack S){
if(StEmpty(S)) exit(202);
return S->c;
}
int Jel_broj(char c){
int d=c;
if(d>=48 && d<=57)
return 1;
return 0;
}
int Jel_operator(char c){
if(c=='+') return 1;
else if(c=='-') return 2;
else if(c=='*') return 3;
else if(c=='/') return 4;
else if(c=='^') return 5;
return 0;
}
int pot(int n, int k){
int l=1;
while(k>0){
l*=n;
k--;
}
return l;
}
void izracunaj(char* niz, int n){
int broj=0, pomocni, j, nn, b1, b2;
stack S;
StMakeNull(&S);
while(n>=0){
if(Jel_broj(niz[n])){
broj=0; j=0; nn=n;
while(Jel_broj(niz[nn])){
j++;
nn--;
}
nn=j;
while(Jel_broj(niz[n-j+1])){
pomocni=niz[n-j+1];
broj=broj*10+(pomocni-'0');
j--;
}
StPush(&S, broj);
n=n-nn+1;
}
else if(Jel_operator(niz[n])){
if(Jel_operator(niz[n])==1){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1+b2);
}
else if(Jel_operator(niz[n])==2){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1-b2);
}
else if(Jel_operator(niz[n])==3){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1*b2);
}
else if(Jel_operator(niz[n])==4){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, b1/b2);
}
else if(Jel_operator(niz[n])==5){
b1=StTop(S);
StPop(&S);
b2=StTop(S);
StPop(&S);
StPush(&S, pot(b1,b2));
}
}
n--;
}
printf("%d", StTop(S));
}
int main(){
char *niz=NULL;
int n=0;
char c;
while(1){
scanf("%c", &c);
if(c=='\n'){
niz=(char*)realloc(niz, (++n)*sizeof(char));
niz[n-1]='[=10=]';
break;
}
niz=(char*)realloc(niz, (++n)*sizeof(char));
niz[n-1]=c;
}
izracunaj(niz,n-2);
return 0;
}
规则说 post 代码片段是有充分理由的:不看代码就很难确定问题。以后,总是 post 要看的东西(并遵守代码片段的规则)。
但在这种情况下,即使没有它,我也能很好地猜测发生了什么:8 位类型的有符号溢出。您的堆栈使用 signed char
(或等效)数据类型,或者您正在某处强制转换为这样的值。可能是您使用的整数解析?
您可能将这些值存储为 int
,但是当您将它们放入和取出堆栈时,它们会被截断为 char
值。
void StPush(stack *Sp, char d)
char StTop(stack S)