RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:8:30-17:00
你可能遇到了下面的问题
关闭右侧工具栏

新闻中心

这里有您想知道的互联网营销解决方案
c语言中栈函数 c语言中栈的定义

C语言函数调用栈

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

成都创新互联公司是专业的大理州网站建设公司,大理州接单;提供成都网站建设、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行大理州网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

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

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

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语言板 数据结构 进栈 函数到底怎么写

看一个栈的简单实现,所有代码都写在一个头文件中,实际的话,最好把声明和实现分开。

#ifndef STACK_H

#define STACK_H

class Stack

{

public:

Stack();

Stack(const Stack copy);

Stack operator= (const Stack copy);

~Stack();

int getHeight() const;

bool isEmpty();

bool push(const int e);

bool pop(int e);

bool top(int e) const;

private:

int count;

int element[MAX_SIZE];

};

Stack::Stack()

{

count = 0;

}

Stack::Stack(const Stack copy)

{

this-count = copy.count;

for(int i = 0; i copy.count; i++)

{

element[i] = copy.element[i];

}

}

Stack Stack::operator =(const Stack copy)

{

if(copy != this)

{

this-count = copy.count;

for (int i = 0; i copy.count; i++)

{

element[i] = copy.element[i];

}

}

return *this;

}

Stack::~Stack()

{

count = 0;

}

int Stack::getHeight() const

{

return count;

}

bool Stack::isEmpty()

{

return count == 0;

}

bool Stack::push(const int e)

{

if (getHeight() == MAX_SIZE)

{

return false;

}

element[count++] = e;

return true;

}

bool Stack::pop(int e)

{

if (isEmpty() )

{

return false;

}

e = element[count--];

return true;

}

bool Stack::top(int e) const

{

e = element[count - 1];

return true;

}

#endif

请用C语言编写一个堆栈函数程序

//该程序简单并可正确运行,希望kutpbpb的回答能对你有所帮助!

#includestdio.h

#define N 100

typedef struct

{

int value[N];

int base;

int top;

}Sta;

void print()

{

printf("\n菜单:");

printf("\n1.入栈:");

printf("\n2.出栈:");

printf("\n3.退出:");

}

void printS(Sta S)

{

printf("\n请输出栈中元素:");

for(int i=S.top;i!=S.base;i--)

printf("%d ",S.value[i-1]);

}

void pushS(Sta S,int e)

{

if(S.top==N)

printf("\n栈满");

else

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

}

void popS(Sta S,int e)

{

if(S.top==S.base)

printf("\n栈空");

else

{

e=S.value[--S.top];

printf("\n请输出出栈元素: %d",e);

}

}

void main()

{

Sta S;

int e,choose;

S.base=S.top=0;

do{

print();

printf("\n请输入你的选项:");

scanf("%d",choose);

switch(choose)

{

case 1:

printf("\n请输入入栈元素:");

scanf("%d",e);

pushS(S,e);

printS(S);

break;

case 2:

popS(S,e);

printS(S);

break;

case 3:

default:

break ;

}

if(choose==3)

break;

}while(1);

}

C语言函数调用(栈的实现)

Status StackTraverse(SqStack S, Status (*pFun)(ElemType))

{

while(S.bottom != S.top)

{

pFun(*--S.top);

}

return OK;

}

//visit函数

Status Visit(ElemType e)

{

printf("%d\n", e);

return OK;

}

//调用

StackTraverse(S, Visit);

c语言怎么调用栈函数

给你个例子:

#include

//写好加法,以便调用

int sum(int x1,int x2)

{

int x3=x1+x2;

return x3;

}

void main()

{

int a=0;

int b=0;

int c=0;

printf("请输入两个整数\n");

scanf("%d%d",a,b);

c=sum(a,b);//传递参数给sum()函数,返回他们的和

printf("%d+%d的和是:%d\n",a,b,c);

}

总之:就是你把一种方法写到单独的块,这里就是sum()函数,执行一个单一的功能,在main函数调用就是了!

数据结构实验(用c语言写) 栈的基本操作

//顺序栈

#includestdio.h

#includestdlib.h

#includemalloc.h

#define STACK_INIT_SIZE 100;

#define STACKINCREMENT 10;

typedef struct

{

int *base;

int *top;

int stacksize;

}SqStack;

typedef int ElemType;

int InitStack(SqStack S) //为栈S分配存储空间,并置S为空栈

{

int size = STACK_INIT_SIZE;

S.base=(int *)malloc(size*sizeof(ElemType));

if(!S.base)

return 0;

S.top=S.base; //置栈S为空栈

S.stacksize=STACK_INIT_SIZE;

return 1;

}

int GetTop(SqStack S,int e) //若栈不空,则用e返回S的栈顶元素

{

if(S.top==S.base) return 0;

e=*(S.top-1);

return 1;

}

int Push(SqStack S, int e) /*进栈函数,将e插入栈S中,并使之成为栈顶元素*/

{ if(S.top-S.base=S.stacksize) /*栈满,追加存储空间*/

{

int stackinvrement = STACKINCREMENT;

S.base=(ElemType *) realloc(S.base,(S.stacksize+stackinvrement)*sizeof(ElemType));

if(!S.base)

return 0; /*存储分配失败*/

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

return 1;

}

int Pop(SqStack S,int e)/*出栈函数,若栈S不空,则删除S的栈顶元素,用e返回其值*/

{ if(S.top==S.base) return 0;

e=*--S.top;

return 1;

}

void OutputStack(SqStack S)

{int *q;

q=S.top-1;

for(int i=0;iS.top-S.base;i++)

{

printf("%3d ",*q);q--;}

}

void main()

{

int a,b,c ;

char m;

SqStack s;

InitStack(s);

printf("请输入要进栈的元素个数是:");

scanf("%d",a);

printf("\n请输入要进栈的%d个元素:",a);

for(b=0;ba;b++) {

scanf("%d",c);

Push(s,c); }

do { printf("\n");

printf("*********** 1.输出栈的元素**********\n");

printf("*********** 2.取栈顶元素************\n");

printf("*********** 3.删除栈顶元素**********\n");

printf("*********** 4.退出程序**********\n");

printf("\n请选择一个字符:");

getchar();

scanf("%c",m);

switch(m) {

case '1': printf("\n输出的栈为:");

OutputStack(s);

break;

case '2': GetTop(s,c);

printf("\n栈顶元素为:%d",c);

printf("\n输出的栈为:");

OutputStack(s);

break;

case '3': Pop(s,c);

printf("\n删除的栈顶元素:%d",c);

printf("\n输出的栈为:");

OutputStack(s);

printf("\n");

break;

case '4':break;

default: printf("输入的数字有错,请重新选择!\n"); break;

}

}while(m!='4');

}

//链栈

#includestdio.h

#includestdlib.h

typedef struct SNode

{

int data;

struct SNode *next;

}SNode,*LinkStack;

LinkStack top;

LinkStack PushStack(LinkStack top,int x) //入栈

{

LinkStack s;

s=(LinkStack)malloc(sizeof(SNode));

s-data=x;

s-next=top;

top=s;

return top;

}

LinkStack PopStack(LinkStack top) //退栈

{

LinkStack p;

if(top!=NULL)

{

p=top;

top=top-next;

free(p);

printf("退栈已完成\n");

return top;

}

else printf("栈是空的,无法退栈!\n"); return 0;

}

int GetStackTop(LinkStack top) //取栈顶元素

{

return top-data;

}

bool IsEmpty()//bool取值false和true,是0和1的区别,bool只有一个字节,BOOL为int型,bool为布尔型

{

return top==NULL ? true:false;

}

void Print()

{

SNode *p;

p=top;

if(IsEmpty())

{

printf("The stack is empty!\n");

return;

}

while(p)

{

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

p=p-next;

}

printf("\n");

}

void main()

{

int x,a,b;

char m;

do { printf("\n");

printf("###############链栈的基本操作##################\n");

printf("××××××××1.置空栈××××××××××\n");

printf("××××××××2.进栈×××××××××××\n");

printf("××××××××3.退栈×××××××××××\n");

printf("××××××××4.取栈顶元素××××××××\n");

printf("××××××××5.退出程序×××××××××\n");

printf("##############################################\n");

printf("\n请选择一个字符:");

scanf("%c",m);

switch(m){

case '1':

top=NULL;

printf("\n栈已置空!");

break;

case '2':

printf("\n请输入要进栈的元素个数是:");

scanf("%d",a);

printf("\n请输入要进栈的%d个元素:",a);

for(b=0;ba;b++) {

scanf("%d",x);

top=PushStack(top,x); }

printf("进栈已完成!\n");

printf("\n输出栈为:");

Print();

break;

case '3':

printf("\n操作之前的输出栈为:");

Print();

top=PopStack(top);

printf("\n操作过后的输出栈为:");

Print();

break;

case '4':

printf("\n输出栈为:");

Print();

if(top!=NULL)

printf("\n栈顶元素是:%d\n",GetStackTop(top));

else

printf("\n栈是空的,没有元素!");

break;

case '5':break;

default:

printf("\n输入的字符不对,请重新输入!");

break;

}

getchar();

}while(m!='5');

}


网页名称:c语言中栈函数 c语言中栈的定义
标题链接:http://lswzjz.com/article/doojdij.html