您的位置:

c语言怎么实现通用栈的简单介绍

c语言怎么实现通用栈的简单介绍

更新:

本文目录一览:

C语言函数调用栈

程序的执行过程可看作连续的函数调用。当一个函数执行完毕时,程序要回到调用指令的下一条指令(紧接call指令)处继续执行。函数调用过程通常使用堆栈实现,每个用户态进程对应一个调用栈结构(call stack)。编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。

不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一样的。

寄存器是处理器加工数据或运行程序的重要载体,用于存放程序执行中用到的数据和指令。因此函数调用栈的实现与处理器寄存器组密切相关。

AX(AH、AL):累加器。有些指令约定以AX(或AL)为源或目的寄存器。输入/输出指令必须通过AX或AL实现,例如:端口地址为43H的内容读入CPU的指令为INAL,43H或INAX,43H。目的操作数只能是AL/AX,而不能是其他的寄存器。 [5]

BX(BH、BL): 基址寄存器 。BX可用作间接寻址的地址寄存器和 基地址寄存器 ,BH、BL可用作8位通用数据寄存器。 [5]

CX(CH、CL):计数寄存器。CX在循环和串操作中充当计数器,指令执行后CX内容自动修改,因此称为计数寄存器。 [5]

DX(DH、DL):数据寄存器。除用作通用寄存器外,在 I/O指令 中可用作端口 地址寄存器 ,乘除指令中用作辅助累加器。 [5]

2.指针和 变址寄存器

BP( Base Pointer Register):基址指针寄存器。 [5]

SP( Stack Pointer Register): 堆栈指针寄存器 。 [5]

SI( Source Index Register):源变址寄存器。 [5]

DI( Destination Index Register):目的变址寄存器。 [5]

函数调用栈的典型内存布局如下图所示:

图中给出主调函数(caller)和被调函数(callee)的栈帧布局,"m(%ebp)"表示以EBP为基地址、偏移量为m字节的内存空间(中的内容)。该图基于两个假设:第一,函数返回值不是结构体或联合体,否则第一个参数将位于"12(%ebp)" 处;第二,每个参数都是4字节大小(栈的粒度为4字节)。在本文后续章节将就参数的传递和大小问题做进一步的探讨。 此外,函数可以没有参数和局部变量,故图中“Argument(参数)”和“Local Variable(局部变量)”不是函数栈帧结构的必需部分。

其中,主调函数将参数按照调用约定依次入栈(图中为从右到左),然后将指令指针EIP入栈以保存主调函数的返回地址(下一条待执行指令的地址)。进入被调函数时,被调函数将主调函数的帧基指针EBP入栈,并将主调函数的栈顶指针ESP值赋给被调函数的EBP(作为被调函数的栈底),接着改变ESP值来为函数局部变量预留空间。此时被调函数帧基指针指向被调函数的栈底。以该地址为基准,向上(栈底方向)可获取主调函数的返回地址、参数值,向下(栈顶方向)能获取被调函数的局部变量值,而该地址处又存放着上一层主调函数的帧基指针值。本级调用结束后,将EBP指针值赋给ESP,使ESP再次指向被调函数栈底以释放局部变量;再将已压栈的主调函数帧基指针弹出到EBP,并弹出返回地址到EIP。ESP继续上移越过参数,最终回到函数调用前的状态,即恢复原来主调函数的栈帧。如此递归便形成函数调用栈。

EBP指针在当前函数运行过程中(未调用其他函数时)保持不变。在函数调用前,ESP指针指向栈顶地址,也是栈底地址。在函数完成现场保护之类的初始化工作后,ESP会始终指向当前函数栈帧的栈顶,此时,若

栈的基本操作的实现(c语言),高手速来!!

/*程序错误太多*/ #include"stdio.h"

#include"stdlib.h"

#include"time.h"

#include"malloc.h"

#define

STACK_INIT_SIZE

10

//栈容量 typedef

struct

SqStack

{

int

top;

//栈顶当前指针

int

*base;

//栈空间数组

}SqStack; void

InitStack(SqStack

S);

//构造空栈S

int

Push(SqStack

S,int

e);

//入栈(栈地址,入栈数据)

返回0对,-1错

int

Pop(SqStack

S);

//出栈

(栈地址)返回栈顶数据

int

StackLength(SqStack

S);

//返回站的元素个数,即求栈长

void

Print_S(SqStack

S);

//显示栈内数据 int

main()

{

SqStack

S;

int

i=0;

int

a,e;

InitStack(S);

srand((unsigned)time(NULL));

//srand((unsigned)time(NULL))以time函数值(当前时间)作为种子

printf("随机填充5个元素为:

");

while(

i5)

{

a

=

rand()%100;

printf("%d

",

a);

Push(S,a);

i++;

}

Print_S(S);

printf("请输入要插入栈顶的元素:");

scanf("%d",e);

Push(S,e);

Print_S(S);

printf("再弹出的栈顶元素为:%d

\n",Pop(S));

printf("栈的长度为:%d

\n",StackLength(S));

Print_S(S);

return

0;

} void

InitStack(SqStack

S)

//构造空栈S

{

S.base

=

(int

*)malloc(STACK_INIT_SIZE

*

sizeof(int));

//分配组数空间,长度STACK_INIT_SIZE

if

(S.base==NULL)

{

printf("内存分配失败!\n");

return;

}

S.top=-1;

} int

Push(SqStack

S,int

e)

{

if(S.top=STACK_INIT_SIZE)

{

printf("栈空间已满,入栈失败!\n");

return

-1;

}

else

{

S.base[++S.top]=e;

return

0;

}

} int

Pop(SqStack

S)

//返回栈顶数据

{

if

(S.top=0)

//栈内有数据

{

return

S.base[S.top--];

}

else

{

printf("空栈,无数据弹出!\n");

return

-1;

}

} int

StackLength(SqStack

S)

{

return

S.top+1;

} void

Print_S(SqStack

S)

{

printf("\n出栈显示:");

if(S.top

==

-1)

printf("栈内无数据!\n");

else

{

while(S.top=0

)

printf("%d

",Pop(S));

putchar('\n');

}

}

栈的c语言实现基本操作

写了一个链式栈,你看看

# include stdio.h

# include malloc.h

# include stdlib.h

typedef struct Node

{

int data;

struct Node *pNext;

}NODE, *PNODE;

typedef struct Stack

{

PNODE pTop;

PNODE pBottom;//pBottem是指向栈底下一个没有实际意义的元素

}STACK, *PSTACK;

void init( PSTACK );

void push( PSTACK, int );

void traverse( PSTACK );

int pop( PSTACK, int * );

int empty( PSTACK pS );

int main( void )

{

STACK S;//STACK等价于struct Stack

int val;

init( S );//目的是造出一个空栈

push( S, 1 );//压栈

push( S, 2 );

push( S, 3 );

push( S, 4 );

push( S, 5 );

push( S, 6 );

push( S, 7 );

traverse( S );//遍历输出

// clear( S ); //清空数据

// traverse( S );//遍历输出

if( pop( S, val ) )

{

printf( "出栈成功,出栈的元素是%d\n", val );

}

else

{

printf( "出栈失败" );

}

traverse( S );//遍历输出出栈之后的元素

return 0;

}

void init( PSTACK pS )

{

pS-pTop = ( PNODE )malloc( sizeof( NODE ) );

if( NULL == pS-pTop )

{

printf( "动态内存分配失败!\n" );

exit( -1 );

}

else

{

pS-pBottom = pS-pTop;

pS-pTop-pNext = NULL;//或是pS-pBottom = NULL;

}

}

void push( PSTACK pS, int val )

{

PNODE pNew = ( PNODE )malloc( sizeof( NODE ) );

pNew-data = val;

pNew-pNext = pS-pTop;//pS-Top不能改为pS-pBottom

pS-pTop = pNew;

}

void traverse( PSTACK pS )

{

PNODE p = pS-pTop;

while( p != pS-pBottom )

{

printf( "%d ", p-data );

p = p-pNext;

}

printf( "\n" );

}

int empty( PSTACK pS )

{

if( pS-pTop == pS-pBottom )

return 1;

else

return 0;

}

//把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,如果出栈失败,则返回false,否则true

int pop( PSTACK pS, int *pVal)

{

if( empty( pS ) )//pS本身存放的就是S的地址

{

return 0;

}

else

{

PNODE r = pS-pTop;

*pVal = r-data;

pS-pTop = r-pNext;

free( r );

r = NULL; //为什么要把r赋给NULL呢??

return 1;

}

}

//clear清空

void clear( PSTACK pS )

{

if( empty( pS ) )

{

return ;

}

else

{

PNODE p = pS-pTop;

PNODE q = p-pNext;

while( p != pS-pBottom )

{

q = p-pNext;

free( p );

p = q;

}

pS-pTop = pS-pBottom;

}

}

C语言,栈的实现~

#includestdio.h

#includemalloc.h

//enum bool {false,true};

typedef struct Node{

int a;

int Number; //在栈中的序号,栈底为0

struct Node *next;

}Node,*LpNode;

typedef struct SqStack{

Node *top;

Node *prev;

Node *base;

int length;

}*LpSqStack;

//将e的能容复制到S中并将e摧毁

bool Node_evaluation(LpNode S,LpNode e,bool M)

{

//赋值操作

//S-Number = e-Number;

if(M == true) free(e);

return true;

}

bool InitStack(LpSqStack S)

{

S-length = 0;

S-base = (LpNode)malloc(sizeof(Node));

if(!S-base) return false;

S-top = S-base;

S-prev = S-base;

S-base-Number = 0;

return true;

}

bool StackEmpty(LpSqStack S)

{

if(S-top != S-base) return false;

return true;

}

bool GetTop(LpSqStack S,LpNode e)

{

if(S-top == S-base) return false;

e = S-top;

return true;

}

bool Push(LpSqStack S,LpNode e)

{

if(!Node_evaluation(S-top,e,true)) return false;

S-top-Number = S-prev-Number + 1;

S-prev = S-top;

S-top = (LpNode)malloc(sizeof(Node));

S-prev-next = S-top;

S-top-next = NULL;

return true;

}

bool Pop(LpSqStack S,LpNode e)

{

if(S-top == S-base) return false;

if(!Node_evaluation(e,S-top,true)) return false;

S-top = S-prev;

S-top-next = NULL;

return true;

}

bool Vistit(LpSqStack S,LpNode e,int i)

{

LpNode p;

p = S-base;

for(int j = 0; j = i; j++)

{

if(p-next == NULL) return false;

p = p-next;

}

if(!Node_evaluation(p,e,false)) return false;

return true;

}

int main()

{

SqStack a;

InitStack(a);

LpNode b=new Node;

LpNode c=new Node;

LpNode d=new Node;

//free(b);这free了你下面又赋值。。。

b-a=1;

Push(a,c);

GetTop(a,c);

printf("%d",c-a);

return 0;

}

栈里的内存是不能free的,你要free你就自己在堆里分配。

c语言怎么实现通用栈的简单介绍

本文目录一览: 1、C语言函数调用栈 2、栈的基本操作的实现(c语言),高手速来!! 3、栈的c语言实现基本操作 4、C语言,栈的实现~ C语言函数调用栈 程序的执行过程可看作连续的函数调用。当一个函

2023-12-08
c到c语言笔记的简单介绍

2022-11-24
基础c语言笔记,C语言笔记

2023-01-06
栈区c语言简介,c++栈区

2023-01-04
c语言为啥用栈,c语言如何用栈

2023-01-06
一篇c语言笔记,c语言入门笔记

2022-12-02
c语言笔记讲解,c语言程序笔记

2022-11-23
c语言知识笔记,c语言最全笔记

2023-01-04
c到c语言笔记,cc在c语言

2022-11-27
c语言随笔讲解,c语言编程讲解

2022-11-27
二级c语言怎么过呀,c语言二级技巧

2023-01-04
精通c语言面试的简单介绍

2022-11-25
c语言栈的内容,c语言栈的实现

2023-01-04
git是c语言写的的简单介绍

2023-01-05
老人学c语言,c语言怎么学

2022-11-30
恶补c语言打卡的简单介绍

2023-01-03
onlinejudge用c语言应注意什么的简单介绍

本文目录一览: 1、C语言及Online Judge System的问题 2、C语言在编程的时候应注意什么问题? 3、我想在Onlinejudge做些c语言的题,但不知道先在如何登录,求指点 C语言及

2023-12-08
onlinejudge用c语言应注意什么的简单介绍

本文目录一览: 1、C语言及Online Judge System的问题 2、C语言在编程的时候应注意什么问题? 3、我想在Onlinejudge做些c语言的题,但不知道先在如何登录,求指点 C语言及

2023-12-08
c语言编写技巧的简单介绍

2022-11-22
c语言出栈指令,c语言进栈出栈完整代码

2022-11-26