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. 栈的头文件
//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.栈的实现
//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. 栈的使用示例
//main.c
//栈的使用示例
#include<stdio.h>
#include"stack.h"
int main(void){//定义栈stack_t s;//栈的初始化:容量为11stack_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.创建一个文件夹
mkdir stack
2.创建三个文件
其中stack.c
表示的是(栈的实现)
其中stack.h
表示的是栈的头文件(栈的定义)
其中main.c
表示的是(栈的使用)
touch stack.c
touch stack.h
touch main.c
stack.c
和stack.h
写完之后验证一下有没有语法错误,看我的stack.o的文件能不能成功生成
gcc -c stack.c
- 生成最终的可执行文件
gcc main.c stack.c -o stack
- 运行程序
./stack
- 运行之后的结果:
11 10 9 8 7 6 5 4 3 2 1