目录
1.定义与概念
2.代码实现
3.结果
1.定义与概念栈
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。
viod *malloc(size_t size)
向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
realloc原型是extern void *realloc(void *mem_address, unsigned int newsize);
先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
2.代码实现/*********************************************/
/* 使用栈将二进制转换成八/十/十六进制 */
/* By Jo 17/05/01 */
/********************************************/
#include
#include
#include
#define STACK_INIT_SIZE 20 //栈初始化大小
#define STACKINCREMENT 10 //栈扩容时每次增加大小
typedef char ElemType; //以字符形式存储二进制数据
typedef struct
{
ElemType *base; //栈低指针
ElemType *top; //栈顶指针
int stackSize; //栈尺寸
}sqStack;
//函数功能:初始化栈(为栈分配内存空间)
//参数*s :栈对象地址
void InitStack(sqStack *s)
{
s->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType));
if (!s->base) exit(0);
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
//函数功能:数据入栈
//参数 *s :栈对象地址
//参数 e :待入栈数据
void Push(sqStack *s, ElemType e)
{
if (s->top - s->base >= s->stackSize) //栈当前容量大于存储容量,拓展栈大小
{
s->base = (ElemType*)realloc(s,(STACK_INIT_SIZE + STACKINCREMENT) * sizeof(ElemType));
if (!s->base) exit(0);
}
*(s->top) = e;
s->top++;
}
//函数功能:数据出栈
//参数 *s :栈对象地址
//参数 *e :待存放出栈数据的对象地址
void Pop(sqStack *s, ElemType *e)
{
if (s->base == s->top) return;
*e = *--(s->top); //栈始终指向栈顶,所以栈顶指针先减1再取出值
}
//函数功能:获取栈长度
//参数s :栈数据对象
//(函数若要修改实参,使用指针->;若只是查询等不修改实参,使用对象本身.)
int StackLen(sqStack s)
{
return (s.top - s.base);
}
//函数功能:清空栈
//参数 *s :栈对象地址
void ClearStack(sqStack *s)
{
s->top = s->base;
}
//函数功能:销毁栈
//参数 *s :栈对象地址
void DestoryStack(sqStack *s)
{
int i, len;
len = s->stackSize;
for (i = 0; i < len; i++)
{
free(s->base); //从栈底逐数据释放
s->base++;
}
s->top = s->base = NULL;
s->stackSize = 0;
}
//函数功能:十六进制转换
//参数 c :待转换成十六进制表示的字符
char ToHexChar(char c)
{
switch (c)
{
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return 'E';
case 15:
return 'F';
default:
return c+48; //字符‘0-9’转换到数字0-9
}
}
int main()
{
//1.二进制转换成十进制
/*
ElemType c;
sqStack s;
int len, i, sum = 0;
InitStack(&s);
printf("输入二进制数 以#结束! \n");
scanf("%c",&c); //每次从键盘缓存区只读一个字符
while (c != '#')
{
Push(&s, c);
scanf("%c",&c);
}
getchar(); //把‘\n’从缓存区中去掉
len = StackLen(s);
printf("二进制栈当前容量为:%d \n",len);
for (i = 0; i < len; i++)
{
Pop(&s, &c);
sum = sum + (c - 48)*pow(2, i);
}
printf("二进制转换成十进制为:%d \n", sum);
*/
//2.二进制转换成八进制
/*
ElemType c;
sqStack s, sOct;
int len, lenOct, i, temp = 0;
InitStack(&s);
InitStack(&sOct);
printf("输入二进制数 以#结束! \n");
scanf("%c", &c); //每次从键盘缓存区只读一个字符
while (c != '#')
{
Push(&s, c);
scanf("%c", &c);
}
getchar(); //把‘\n’从缓存区中去掉
len = StackLen(s);
printf("二进制栈当前容量为:%d \n", len);
int count = 0;
for (i = 0; i < len; i++)
{
Pop(&s, &c);
temp = temp + (c - 48)*pow(2, count);
count++;
if (count == 3 || (s.top == s.base))
{
Push(&sOct, temp); //低位放在栈底
temp = 0;
count = 0;
}
}
lenOct = StackLen(sOct);
printf("八进制栈当前容量为:%d \n", lenOct);
printf("二进制转换成八进制为:");
for (i = 0; i < lenOct; i++)
{
Pop(&sOct, &c);
printf("%d", c);
}
*/
//3.二进制转换成十六进制
///*
ElemType c;
sqStack s, sHex;
int len, lenHex, i, temp = 0;
InitStack(&s);
InitStack(&sHex);
printf("输入二进制数 以 # 结束! \n");
scanf("%c", &c); //每次从键盘缓存区只读一个字符
while (c != '#')
{
Push(&s, c);
scanf("%c", &c);
}
getchar(); //把‘\n’从缓存区中去掉
len = StackLen(s);
printf("二进制栈当前容量为:%d \n", len);
int count = 0;
for (i = 0; i < len; i++)
{
Pop(&s, &c);
temp = temp + (c - 48)*pow(2, count);
count++;
if (count == 4 || (s.top == s.base)) //与八进制的重要区别
{
Push(&sHex, temp); //低位放在栈底
temp = 0;
count = 0;
}
}
lenHex = StackLen(sHex);
printf("十六进制栈当前容量为:%d \n", lenHex);
printf("二进制转换成十六进制为:");
char tempChar;
for (i = 0; i < lenHex; i++)
{
Pop(&sHex, &c);
tempChar = ToHexChar(c);
printf("%c", tempChar);
}
//*/
return 0;
}
3.结果