栈的结构定义
通常用数组来模拟栈,这个比较简单实用,也可以用指针.为了简单,这里仅演示用数组模拟的版本
#define MAX_STACK_SIZE 100
// 定义栈的结构
typedef struct stack{
int data[MAX_STACK_SIZE]; //栈的数组空间大小,储存栈的数据
int top; //栈顶
}Stack;
栈的相关核心代码
初始化栈
也就是让栈顶指针top达到一个不可能到达的值
void iniStack(Stack* s)
{
s-> top=-1;
}
判断栈是否为空
如果栈顶指针top是-1的话,表达式返回真值,否则返回假值,这样直接return可以少写几行代码
bool isEmpty(Stack* s)
{
return s->top==-1;
}
判断栈是否为满
同样的思路,由于数组下标是从0开始的(0位置储存第一个元素),到满时应该是最大值-1而不是最大值
bool isFull(Stack* s)
{
return s->top==MAX_STACK_SIZE-1;
}
压栈(Push)
压栈可以使用void类型,单纯的添加元素即可.如果有特殊需求可以修改函数的返回值类型特殊修改就好
// 压栈时,使用void类型的就好,因为压栈就是单纯的加入元素
void Push(Stack* s,int value)
{
if(isFull(s))
{
printf("栈已满\n");
return;
}
s->data[++s->top]=value;
}
注意这里的++s->top是前置递增 意思是先让top指针+1后再将数组中top位置的值修改为value(用一开始top为-1然后++为0代表第一个元素可以方便理解)
出栈(Pop)
出栈需要使用int返回值类型,因为在后期的实际运用通常需要使用栈顶的元素
// Pop时,通常需要使用栈顶元素,所以用int以及后置递减
int Pop(Stack* s)
{
if(isFull(s))
{
printf("栈已空\n");
return -1;
}
return s->data[s->top--]; // 先返回栈顶元素 再将栈顶指针向下移动
}
注意这里的s->top-- 先返回栈顶元素 再将栈顶指针向下移动 ,而不是先向下移动再返回栈顶元素,因为如果先向下移动,实际上的栈顶元素就被略过了
利用栈实现进制转换的完整代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX_STACK_SIZE 100
typedef struct {
int data[MAX_STACK_SIZE];
int top;
} Stack;
void initStack(Stack* s) {
s->top = -1;
}
bool isEmpty(Stack* s) {
return s->top == -1;
}
bool isFull(Stack* s) {
return s->top == MAX_STACK_SIZE - 1; //数组的特性(从0开始)
}
void push(Stack* s, int value) {
if (isFull(s)) {
printf("栈已满\n");
return;
}
s->data[++s->top] = value;
}
int pop(Stack* s) {
if (isEmpty(s)) {
printf("栈为空\n");
return -1;
}
return s->data[s->top--];
}
void convertToBase(int number, int base) {
Stack s;
initStack(&s);
int isNegative = 0;
// 处理负数情况
if (number < 0) {
isNegative = 1;
number = -number;
}
// 压栈
while (number != 0) {
push(&s, number % base);
number /= base;
}
// 在负数情况下输出负号
if (isNegative) {
printf("-");
}
if (base == 8) {
printf("0"); // 加上八进制的表示前缀 0
}
else if (base == 16) {
printf("0x"); // 加上十六进制的表示前缀 0x
}
while (!isEmpty(&s)) {
int remainder = pop(&s);
if (remainder < 10) {
printf("%d", remainder);
}
else {
printf("%c", (remainder - 10) + 'A'); // 处理十六进制情况
}
}
printf("\n");
}
int main() {
int number, base, choice;
do {
printf("\n进制转换模拟:\n");
printf("1. 转化为二进制\n");
printf("2. 转化为八进制\n");
printf("3. 转化为十六进制\n");
printf("4. 退出\n");
printf("请输入你的选择: ");
scanf("%d", &choice);
switch (choice) {
case 1:
base = 2;
break;
case 2:
base = 8;
break;
case 3:
base = 16;
break;
case 4:
return 0;
default:
printf("无效选项,请重新输入.\n");
continue;
}
printf("请输入你打算转化的数字: ");
if (scanf("%d", &number) != 1) { //scanf 函数返回成功读取并赋值的变量数量。如果成功读取了一个整数,scanf 将返回 1。
printf("非法输入,请重新输入.\n");
continue;
}
if (number == 0) {
printf("被除数不能为0\n");
continue;
}
convertToBase(number, base);
} while (choice != 4); // 如果用户不选择退出则继续运行
return 0;
}