c語言函數棧
Ⅰ c語言中的棧、堆是什麼
C語言中的堆和棧都是一種數據項按序排列的數據結構。
棧就像裝數據的桶或箱子
我們先從大家比較熟悉的棧說起吧,它是一種具有後進先出性質的數據結構,也就是說後存放的先取,先存放的後取。
這就如同我們要取出放在箱子裡面底下的東西(放入的比較早的物體),我們首先要移開壓在它上面的物體(放入的比較晚的物體)。
堆像一棵倒過來的樹
而堆就不同了,堆是一種經過排序的樹形數據結構,每個結點都有一個值。
通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。
由於堆的這個特性,常用來實現優先隊列,堆的存取是隨意,這就如同我們在圖書館的書架上取書。
雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同於箱子,我們可以直接取出我們想要的書。
(1)c語言函數棧擴展閱讀:
關於堆和棧區別的比喻
使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。
參考資料來源:網路-堆棧
Ⅱ C語言 入棧順序為什麼函數入棧順序從右往左
C語言函數參數入棧順序從右到左是為了方便可變參數函數。
一、在函數調用時,函數參數的傳遞,在C語言中是通過棧數據結構實現的。
在調用函數時,先根據調用函數使用的參數,自右向左依次壓入棧中,然後調用函數,在函數開始執行時,將參數再依次彈棧。根據棧數據結構先進後出的特點,在函數中彈棧的順序就是從左向右的。
二、對於參數固定的函數,無論是從左向右還是從右向左,都沒什麼區別,最終都是所有參數全部傳遞。
三、對於可變參數,比如printf,會在第一個參數格式字元串中,指明後續有幾個參數,各自是什麼類型的。於是在函數中,參數格式字元串必須第一個彈棧,否則無法獲取參數類型,也就無法獲知後續參數占幾個位元組,導致無法正確獲知參數。
四、理論上來說,如果從左向右壓棧,可變參數標記格式字元串的參數放在最後,那麼也是可以的。 不過最早設計C語言的人採用了這種方式,後續也就延續下來了。
Ⅲ C語言中函數參數壓棧方式為什麼是從右到左
棧是先入後出的數據結構.
函數參數從右到左, 那麼到函數內部出棧的時候就是從左到右的順序了.
對於普通函數無區別. 但對於可變參函數, 會根據左側參數來決定共計有多少參數, 每個類型是什麼.
比如 printf scanf這類的.
於是 就設計成從右到左的壓棧方式了.
Ⅳ 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<malloc.h>
#definestack_init_size20
#defineincreasesize10;
typedefintElemType;
typedefstructnode{
ElemType*base;
ElemType*top;
intsize;
}stack;
voidcreat(stack*s)
{
s->base=(ElemType*)malloc(sizeof(ElemType));
if(!s->base)
{
exit(0);
}
s->base=s->top;
s->size=stack_init_size;
}
voidpush(stack*s,ElemTypee)
{
if(s->top-s->base>=s->size)
{
s->base=(ElemType*)realloc(s->base,(s->size+increasesize)*sizeof(ElemType));
if(!s->base)
{
exit(0);
}
s->top=s->base+s->size;
s->size+=increasesize;
}
*(s->top)=e;
s->top++;
}
voidpop(stack*s,ElemType*e)
{
if(s->top==s->base)
{
return;
}
*e=*--(s->top);
}
intstacklen(stacks)
{
return(s.top-s.base);
}
intmain()
{
stacks;
intn;
ElemTypee1,e2,d;
inti=1,j=1;
push(&s,i);
push(&s,j);
scanf("%d",&n);
while(n--)
{
pop(&s,&e1);
pop(&s,&e2);
d=e1+e2;
push(&s,e2);
push(&s,d);
}
pop(&s,&d);
printf("%d",d);
return0;
}
Ⅵ C語言中,什麼是棧,什麼是堆
1、棧區(stack):由編譯器自動分配釋放,存放函數的參數值,局部變數等值。局部變數,任務線程函數之類的是放在(使用)棧裡面的,棧利用率高一些。其操作方式類似於數據結構中的棧。特別,棧是屬於線程的,每一個線程會有一個自己的棧。
2、堆區(heap):一般由程序員分配釋放,若程序員不釋放,則可能會引起內存泄漏。注意它和數據結構中的堆是兩回事,分配方式倒是類似於鏈表,常見的就是malloc出來的都是屬於堆區,就像固定出來的區域,到free的時候才釋放,有點類似全局的,靜態的。
(6)c語言函數棧擴展閱讀
棧內存是由編譯器自動分配與釋放的,它有兩種分配方式:靜態分配和動態分配。
1、靜態分配是由編譯器自動完成的,如局部變數的分配(即在一個函數中聲明一個int類型的變數i時,編譯器就會自動開辟一塊內存以存放變數i)。
2、動態分配由alloca函數進行分配,但是棧的動態分配與堆是不同的,它的動態分配是由編譯器進行釋放,無需任何手工實現。
Ⅶ c語言:函數調用時,棧的問題——(有請高手高手高高手)
必須出棧!
aa 和 bb 和c 都是函數內部的局部變數,函數返回後就被釋放,也就是在棧中沒有了,返回後就剩下圖中main()函數所對應的棧結構.
棧只能夠通過出棧來減少棧中數據的個數,從反面來講,如果不出棧,funcA()函數返回後,棧指針還是指向c那,這肯定是不對的,因為函數返回後棧指針就得指向man()的棧結構了。
Ⅷ C語言中的棧和堆是什麼
1、計算機中的內存分為兩部分:一部分是棧(stack,也稱堆棧),另一部分是堆(heap)。
2、 棧,可以看作是一摞卡片,最上面的卡片表示程序的當前作用域,這往往就是當前正在執行的函數。
3、堆,一段完全獨立於當前函數或者棧幀的內存區。如果一個函數中聲明了一些變數,而且希望當這個函數完成時其中聲明的變數仍然存在,就可以將這些變數置於堆中。