棧
區域性變數和函式引數通常儲存在棧中。函式呼叫時,棧空間用於儲存函式引數、返回地址和區域性變數。
int func(const char *str1, char *str2, int count)
{
count++;
printf("%s %s\n", str1, str2);
return count;
}
在這個函式中,引數,區域性變數都是儲存在棧上的,等函式返回後,棧就會銷燬,這些變數也會被釋放,所以函式外訪問不到他們
注意這裡有兩個引數是指標,表示是引用傳遞,但這並不意味這你就能修改他們,加上const關鍵字修飾引數(限制對變數的修改),可以保護這個變數不被修改,如果不加,你也要考慮到實際引數是否可以被修改,即實際引數是否是個常量
堆
動態分配的記憶體(使用 malloc、calloc 等)儲存在堆中。堆記憶體的生命週期是由程式設計師控制的。
char *p = malloc(2 * sizeof(char));
free(p);
p也是一個變數,但它並不儲存在堆區中,它只是指向堆中分配的記憶體
全域性/靜態儲存區
靜態變數和全域性變數儲存在靜態儲存區,生命週期從程式開始到結束。
int global_v = 0; // 全域性變數
void func()
{
static local = 1; // 靜態變數,只會初始化一次
}
常量區
字面量常量和一些常量資料儲存在常量區。
- 字串字面量,比如
"hello"
- 使用 const 修飾的變數,比如
const int a;
- 編譯時常量(如 #define 和 enum)
特殊
void func()
{
char *str1 = "hello"; // 常量區
char str2[] = "world"; // 棧
}
在上述這個例子中,str1和str2都是區域性變數,但是str1指向的"hello"
是儲存在常量區的,str1這個指標指向他,str2是一個陣列,"world"
以陣列的形式儲存在棧上,即{'w', 'o', 'r', 'l', 'd', '\0'}
這6個位元組,函式返回後會被銷燬
主要的原因還是,編譯器對他們的解釋不同吧,一個解釋為字串常量,一個解釋為陣列