程式語言入門/棧
外觀
< 程式語言入門
也許,程式中最常見的變數是區域性變數,也稱為自動變數。在我們的例子中,變數`auto_var`和`auto_const`是區域性變數。這些變數具有區域性作用域:它們只存在於宣告它們的函式內部,並且在函式返回時會丟失它們的值。但是,為什麼呢?
每次呼叫函式時,都會建立一個名為啟用記錄(或棧幀)。啟用記錄是棧的一部分,用於在函式呼叫時儲存函式的資料。因此,啟用記錄儲存函式的引數、區域性變數、返回地址等。函式的啟用記錄僅在函式執行時存在。結束後,其啟用記錄會被銷燬,從而銷燬函式資料。這就是為什麼區域性變數每次函式結束時都會丟失其值的原因。(記住:靜態變數不會以這種方式工作。它們不是儲存在棧中,而是儲存在資料或bss部分)。
正如我們在之前的圖片中所展示的那樣,棧向下增長,而堆向上增長。這意味著如果在棧上分配了兩個物件,第二個物件的地址將低於第一個物件的地址。
想象一下一個郵遞員在一條街上送郵件。如果他從街道的盡頭開始送郵件,朝著起點走,他將首先送住在房屋編號更高的那些人的郵件。這就是棧分配的工作方式:首先分配的物件具有更高的地址。堆分配的類比是相同的。唯一的區別是郵遞員將從街道的起點開始送郵件,並朝著盡頭走,從而首先送住在地址較低的人的郵件。
下面我們提供了一個小例子來展示它的工作原理。當我們執行下面的程式時,我們看到變數`aux_1`的地址大於`aux_2`的地址,而`aux_2`的地址大於`aux_3`的地址。
#include <stdio.h>
int sum(int a, int b) {
int aux_1 = a;
int aux_2 = b;
int aux_3;
printf("&aux_1 = %lu\n", &aux_1);
printf("&aux_2 = %lu\n", &aux_2);
printf("&aux_3 = %lu\n", &aux_3);
aux_3 = aux_1 + aux_2;
return aux_3;
}
int main() {
printf("Sum = %d\n", sum(2, 3));
}