昨天实现了栈的初始化和压一个数据入栈这两个函数,今天添加一个判断栈是否为空以及出栈这两个函数,并且实现一个简单的数制转换的功能。
首先简单介绍一下数制转换功能,对于任意一个十进制数N,将其转换成d进制数,这里偷懒直接选用书上例子,将十进制数转换成八进制数,过程如下:
N | N/8 | N%8 |
1348 | 168 | 4 |
168 | 21 | 0 |
21 | 2 | 5 |
2 | 0 | 2 |
编译环境VC++6.0,完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#define SElemType int
#define STACK_INIT_SIZE 100
#define STACK_INCRECEMENT 10
#define STATUS int
#define ERROR 0
#define OK 1
#define null 0
#define TRUE 1
#define FALSE 0
typedef struct{
SElemType *top;
SElemType *base;
int stacksize;
}Stack;
STATUS Stack_Init(Stack *s)
{
s->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(s->base == null)return ERROR;
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
return OK;
}
//若栈为空,返回TRUE,否则为FALSE
STATUS StackEmpty(Stack *s)
{
if(s->top == s->base)return TRUE;
else return FALSE;
return OK;
}
STATUS Stack_Pop(Stack *s,SElemType *e)
{
if(s->top == s->base)return ERROR;
*e = *--s->top;//栈顶指针一定要先自减,因为它始终在push入栈的最后一个数据之上
return OK;
}
STATUS Stack_Push(Stack *s,SElemType e)
{
if(s->top - s->base >=STACK_INIT_SIZE)
{
s->base = (SElemType *)realloc(s->base,(s->stacksize+STACK_INCRECEMENT)*sizeof(SElemType));
if(s->base == null)return ERROR;
s->top = s->base + s->stacksize;
s->stacksize += STACK_INCRECEMENT;
}
*s->top++ = e;
return OK;
}
int main()
{
SElemType e;
int n,d;
Stack s;
if(Stack_Init(&s))
{
printf("输入要转换的数:\n");
scanf("%d",&n);
printf("输入转换进制:\n");
scanf("%d",&d);
}
else printf("stack initial error!\n");
while(n)
{
Stack_Push(&s,n%d);
n /=d;
}
while(!StackEmpty(&s))
{
Stack_Pop(&s,&e);
printf("%d",e);
}
printf("\n");
return 0;
}
编写代码的时候要注意的是,对于入栈函数和出栈函数,分别采用了SElemType的变量e和指向SElemType类型变量的指针变量*e,在push函数里面,由于是第一个压入栈的数据元素,所以要对地址为*s->base的空间内存入e,所以采用了变量e;而在pop函数里面,--s->top是最后一个数据的起始地址,将栈顶指针指向此处,说明最后一个数据元素已经删除,而为了改变实参的值,首先考虑用指针传递的方式,因此函数参数使用了*e,而调用时,将变量e的地址传递给指针型形参e,此时的形参e指向了实参e,这样对形参进行赋值操作才能改变实参的值。