C语言栈的实现

C语言栈

c 复制代码
//表示栈
typedef struct stack{
    int* arr;//存储区的首地址
    int top; //控制存和取的操作
    int cap; //存储区的容量
}stack_t;

思路:

入栈操作:





中间都是重复的步骤,就省略了。


出栈操作:





中间都是重复的步骤,就省略了。


栈空的情况:

注意哈,这个top表示的是数组下标。第一个数组的下标为0

栈满的情况:

存储区容量 cap = 11 ,意味着栈最多能存 11 个元素(对应数组下标 0 ~ 10 ,共11个可用位置 )。
top 表示下一个要存入数据的数组下标 ,初始为 0 。每存一个数据,top+1 指向下一个位置 。

top == cap(即 top = 11 )时,说明下一个要存的位置已经超出了数组最大下标(10 ),此时栈里已经存了cap个元素(下标0~10全占满 ),栈满,无法再存新数据。

具体代码实现:

1. 栈的头文件
c 复制代码
//stack.h文件
//栈的头文件,谁包含我的这个头文件,谁就可以用我这个类型的声明和函数的声明
//头文件卫士,避免头文件被重复包含
#ifndef __STACK_H__
#define __STACK_H__

//一.类型的声明
//用结构体表示栈
typedef struct stack{
    int* arr;//存储区的首地址
    int top;//控制存和取的操作
    int cap;//存储区的容量
}stack_t;
//定义栈类型的变量  stack_t s;
//定义变量的同时得初始化,我们可以将这个初始化操作封装到函数void stack_init(stack_t* p,int cap);里面

//二.函数的声明
//栈的初始化
//参数:指向要初始化的栈的指针;栈的容量
//对指针p所指向的栈进行初始化,容量为cap
void stack_init(stack_t* p,int cap);

//栈的释放
//参数:指向要释放的栈的指针
//对指针p所指向的栈进行释放
void stack_deinit(stack_t* p);

//栈的判空
//参数:指向要判断的栈的指针
//如果指针p所指向的栈是空的,返回1;非空则返回0
int stack_empty(stack_t* p);

//栈的判满
//参数:指向要判断的栈的指针
//如果指针p所指向的栈是满的,返回1;非满则返回0
int stack_full(stack_t* p);

//压栈
//第一个参数:指向要存入数据的栈的指针
//第二个参数:要入栈的数据,传入该数据后会被存到指针p所指向的栈里面
void stack_push(stack_t* p,int data);

//弹栈
//参数:指向要取出数据的栈的指针
//从指针p所指向的栈里面取出数据,返回取出的int类型数据
int stack_pop(stack_t* p);

#endif
2.栈的实现
c 复制代码
//stack.c文件
//栈的实现
#include<stdlib.h>//malloc() free()
#include"stack.h"

//栈的初始化
//参数:指向要初始化的栈的指针;栈的容量
//stack_t s; s.arr s.top s.cap
//stack_init(&s,5);//实参
void stack_init(stack_t* p,int cap){//形参
    // p &s; cap = 5;
    // malloc返回值是void*类型,可以强转变成int*,也可以不写,因为编译器会自动进行隐式类型转换
    // 隐式类型转换:整转浮,有转无,小转大
    p->arr = (int*)malloc(sizeof(int) * cap);
    p->top = 0;
    p->cap = cap;
}

//栈的释放
//参数:指向要释放的栈的指针
//stack_t s; s.arr s.top; s.cap
//stack_deinit(&s);//实参
void stack_deinit(stack_t* p){//形参
    free(p->arr);
    p->arr = NULL;
    p->top = 0;
    p->cap = 0;
}

//栈的判空
//参数:指向要判断的栈的指针
//当指针p所指向的栈中没有存储数据(top为0)时,返回1;否则返回0
int stack_empty(stack_t* p){
    if(p->top == 0){
        return 1;
    }else{
        return 0;
    }
}

//栈的判满
//参数:指向要判断的栈的指针
//当指针p所指向的栈中存储数据已满(top等于cap)时,返回1;否则返回0
int stack_full(stack_t* p){
    //return p->top == p->cap ? 1 : 0;
    return p->top == p->cap;
}

//压栈
//参数:指向目标栈的指针;要入栈的数据
//把data的数据存到栈里面,存到arr里面,top作下标,arr[top] = data,存完之后top的值+1
void stack_push(stack_t* p,int data){
    //谁的arr谁的top,结构体里面的呀
    //arr[top] = data;这是错误的

    //p->arr[p->top] = data;
    //p->top++;
    //上面两行可以合成下面一行(先以top的值作为下标完成数据的存储,然后top的值再加一)
    p->arr[p->top++] = data;
}

//弹栈
//参数:指向目标栈的指针
//如何拿数据:top先减一,然后以top作为下标将对应的这块存储区的数据拿出来存在val里面
int stack_pop(stack_t* p){
    //谁的top谁的arr,结构体里面的呀
    //top--;这是错误的
    //int val = arr[top];这是错误的

    p->top--;
    int val = p->arr[p->top];
    return val;
    //上面三行可以合并下面一行(先top的值减1,然后将top的值作为下标完成数据的取)
    //return p->arr[--p->top];
}
3. 栈的使用示例
c 复制代码
//main.c
//栈的使用示例
#include<stdio.h>
#include"stack.h"
int main(void){

    //定义栈
    stack_t s;
    //栈的初始化:容量为11
    stack_init(&s,11);
    int data = 1;
    
    //往栈中依次存入数据:1 2 3 4 5 6 7 8 9 10 11
    //循环结束条件:栈满时停止存入(使用栈满判断函数)
    //stack_full(&s)返回1表示栈满,返回0表示栈未满
    while(stack_full(&s) != 1){
        stack_push(&s,data);
        data++;
    }
    
    //从栈中依次取出数据并打印
    //循环结束条件:栈空时停止取出(使用栈空判断函数)
    //stack_empty(&s)返回1表示栈空,返回0表示栈非空
    while(stack_empty(&s) != 1){
        printf("%d ",stack_pop(&s));
    }
    printf("\n");

    //释放栈资源
    stack_deinit(&s);

    return 0;
}
4. linux关于这个的使用步骤

1.创建一个文件夹

bash 复制代码
mkdir stack

2.创建三个文件

其中stack.c表示的是(栈的实现)

其中stack.h表示的是栈的头文件(栈的定义)

其中main.c表示的是(栈的使用)

bash 复制代码
touch stack.c
touch stack.h
touch main.c
  1. stack.cstack.h写完之后验证一下有没有语法错误,看我的stack.o的文件能不能成功生成
bash 复制代码
gcc -c stack.c
  1. 生成最终的可执行文件
bash 复制代码
gcc main.c stack.c -o stack
  1. 运行程序
bash 复制代码
./stack
  1. 运行之后的结果:
    11 10 9 8 7 6 5 4 3 2 1
相关推荐
cqsztech3 小时前
oracle linux 10 +pg18 源码安装要点
linux·数据库·oracle
奥尔特星云大使3 小时前
ALTER 与 UPDATE、DROP 与 DELETE区别
linux·运维·数据库·mysql
duangww4 小时前
部署sapui5应用到linux
linux·sap fiori
siriuuus4 小时前
Linux ssh/scp/sftp命令使用及免密登录配置
linux·ssh·sftp·scp
teacher伟大光荣且正确6 小时前
Linux 下编译openssl
linux·运维·服务器
dlz08366 小时前
--group-start/--group-end 能不能解决 OpenSSL 1.0 vs 1.1 的优先级问题?
linux·运维·服务器·软件需求
小池先生7 小时前
activemq延迟消息变成实时收到了?
linux·数据库·activemq
tryCbest8 小时前
Linux系统下安装使用Redis
linux·运维·redis
GilgameshJSS8 小时前
STM32H743-ARM例程9-IWDG看门狗
c语言·arm开发·stm32·单片机·嵌入式硬件·学习
Hello_Embed9 小时前
STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
c语言·笔记·stm32·单片机·嵌入式软件·嵌入式项目