关于用栈算法实现数值转换的一些问题,请教各位

fengyoujing 2003-10-28 08:12:46
昨天看数据结构课本,结果讲到栈时它举了个用栈算法的例子,就是数值转换,例如将十进制数转换成8进制数,书上给出了类c的算法,我参考这用c写了个程序,书上函数用的是
传引用调用,我想用传值调用来实现,结果不知道返回值该怎样实现,把自己弄糊涂了,请教各位高手指点迷津,源代码如下:

#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREAMENT 10


typedef struct
{
int *base;
int *top;
int stacksize;
} SqStack;

void InitStack(SqStack);
int StackEmpty(SqStack);
int Push(SqStack,int);
int Pop(SqStack,int);


void InitStack(SqStack s)
{
s.base=(int *)malloc((STACK_INIT_SIZE)*sizeof(int));
if(!s.base) exit(0);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}

int StackEmpty(SqStack s)
{
if(s.top==s.base)
return 1;
else
return 0;
}

int Push(SqStack s,int e)
{
if(s.top-s.base>=s.stacksize)
{
s.base=(int*)realloc(s.base,(s.stacksize+STACKINCREAMENT)*sizeof(int));
if(!s.base) exit(0);
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREAMENT;
}
*s.top++=e;
return s.top;
}


int Pop(SqStack s,int e)
{
if(s.top==s.base) return 0;
e=*--s.top;
return s.top;
}

void main()
{
SqStack s;
int e,N;
InitStack(s);
scanf("%d",N);
while(N)
{
Push(s,N%8);
N=N/8;
}

while(!StackEmpty(s))
{
Pop(s,e);
printf("%d\n",e);
}

}
...全文
102 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
TianGuangZao 2003-11-05
  • 打赏
  • 举报
回复
纠正一句:
再解释一个: int Pop(SqStack s , int e);
改成这个形式 : int Pop(SqStack * sPtr, int *ePtr);
使用时 Pop(&ss, &e); <-----这里
TianGuangZao 2003-11-05
  • 打赏
  • 举报
回复
Ok! 我来谈一点我的经验:

在你的例子中:
typedef struct
{
int *base;
int *top;
int stacksize;
} SqStack;
int Push(SqStack s,int e);

这样写的话,这里传递参数的形式是以传值的方式进行的,比如:
我定义一个顺序堆栈 SqStack ss; 然后把它作为参数传递给 Push 函数:
Push (ss, e);
那么这里 s 就是 ss 这个结构体的一份拷贝,这种方式我们称之为传值,有时候我们还称 s 为形参,ss 为实参。拷贝 s 和原件 ss 是两个独立的,完全无关的实体,这样的话,显然 Push 函数就出问题了。因为 Push 后要修改 top 指针和 stacksize 大小,在函数 Push 里,你修改的是 s.base 和 s.stacksize, 而ss.base , ss.stacksize 的值却没有改变,显然违背了本意。
这里我们把函数定义改一下:
int Push(SqStack *sPtr, int e);
传递一个指向结构的指针 sPtr, 使用时,我们需要传递结构 ss 的地址:
Push( &ss, int e);
如果要修改 top 和 stacksize 数据,使用指针的表示法:
sPtr->top 和 sPtr->stacksize
指针在这里就是一种模拟传引用,它的和传值不同的是,你操纵的是同一个实体。

再解释一个: int Pop(SqStack s , int e);
改成这个形式 : int Pop(SqStack * sPtr, int *ePtr);
使用时 Pop(&ss, e);
因为 Pop 同样要修改结构里的 top 指针和 stacksize,所以采用传递指针参数,e 用来保存 Pop 出来的元素值,所以也需要传递指针,而非传值的方式。

总之,记住下面几点,如果你要修改要操纵的对象,请选择传指针方式,如果并不需要修改对象内容,最安全的方法是传值方式。

除了我上面提到的方法,其实还有一种方法,就是传递一个二级指针。
不过更难理解,就不介绍了。

fengyoujing 2003-10-30
  • 打赏
  • 举报
回复
TianGuangZao(天光早):我也想过用指针,可我指针用得不太熟,你能否说的具体点,谢谢。
laomai(老迈) :你的方法我试过了,还是死循环,而且这样就不能改变e的值了,谢谢你的支持。
laomai 2003-10-29
  • 打赏
  • 举报
回复
你如果想使用值传递,那就必须修改pop的原型,改成
int pop(SqStack)
{
return(--S.top;)
}就可以了
Weigehoho 2003-10-29
  • 打赏
  • 举报
回复
感觉你的书上例子不是很对
最基本的,如果是负数入栈呢,没有体现阿
还有你具体想问什么?我没看懂
TianGuangZao 2003-10-29
  • 打赏
  • 举报
回复
你可以用指针来模拟传引用,而不必用传值的方式。
用这种方式仅需对书本上的例子做少量修改。

fengyoujing 2003-10-29
  • 打赏
  • 举报
回复
楼上的我看的是清华大学出版社出的《数据结构(c语言版)》,严蔚敏和吴伟民编的,例子在48页,呵呵,不好意思,我没说明白,他一开始已经强调是非负十进制整数转化为8进制数了,我想问的是怎么让我定义的那些函数返回有效的值,也就是让这个程序能正确运行。
carbon107 2003-10-28
  • 打赏
  • 举报
回复
void InitStack(SqStack);//初始化栈
int StackEmpty(SqStack);//使栈人空
int Push(SqStack,int);//进栈
int Pop(SqStack,int);//出栈
void main()
{
SqStack s; //定义了一个栈的结构体
int e,N;
InitStack(s); //初始化栈
scanf("%d",N); //输入一个整型数
while(N) //以N定为循环
{
Push(s,N%8) //进栈加N%8;
N=N/8;
}

while(!StackEmpty(s))//栈为空吗
{//不为空
Pop(s,e);//清栈顶
printf("%d\n",e);//输出清出来的是什么
}

}

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧