深入理解C語言 深入理解記憶體四區

2021-09-16 12:30:36 字數 2078 閱讀 6638

當陣列做函式引數的時候,會退化為乙個指標

此時在函式內是得不到陣列大小的

因此,陣列做函式引數的時候需要傳遞陣列大小,也就是多傳遞乙個引數

void

func

(int arr,

int num)

若存在以上函式,c/c++編譯器在編譯的時候,會將陣列優化為乙個指標,指向陣列的首位址,因此無法通過sizeof獲得陣列大小

以下可看作是c/c++編譯器的優化過程

int a[10] => int a => int *p

void

func

(int

*p,int num)

在函式呼叫的時候,實參的值機械的傳遞給形參

形參:

按照上圖,資料型別又可分為簡單資料型別和複雜資料型別

簡單資料型別和複雜資料型別的處理方式不一樣

在處理複雜資料型別的時候,不能按照簡單資料型別的處理方式去處理

例如,存在int a[10]陣列,那麼&a的值和a的值相同,但是&a + 1a + 1的值卻不相同,原因是前者代表的是乙個陣列位址,後者代表的是乙個元素位址,前者加一,指出陣列,而後者加一則是相當於指向下乙個元素的位址,前者移動sizeof(a)位元組,後者移動sizeof(int)位元組

c語言規定陣列名代表陣列首元素位址,&a代表整個陣列

資料型別的本質就是告訴編譯器開闢記憶體的大小,就是乙個指明開闢記憶體大小的說明性標籤,也就是建立變數的模具,是固定記憶體大小的別名

在c語言中,專門有乙個操作符sizeof用來得到資料型別的大小,其大小在編譯時候便已經確定

由於資料型別只是乙個標識,故可以使用typedef定義別名

既能讀又能寫的記憶體物件,稱為變數;若一旦初始化後不能修改的物件則稱為常量

變數本質:(一段連續)記憶體空間的別名,標號

對記憶體可讀可寫

通過變數向記憶體中讀寫資料,而不是像變數讀寫資料

向變數代表的資料空間讀寫資料

c語言規定:通過資料型別,定義變數

流程說明

作業系統把物理硬碟**load到記憶體

作業系統把c**分成四個區

作業系統找到main函式入口執行 區塊

作用棧區(stack)

由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等

堆區(heap)

一般由程式設計師分配釋放(動態記憶體申請與釋放),若程式設計師不釋放,程式結束時可能由作業系統**

全域性區(靜態區)(static)

全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域,該區域在程式結束後由作業系統釋放

常量區字串常量和其他常量的儲存位置,程式結束後由作業系統釋放

程式**區

存放函式體的二進位制**

main()呼叫fa(),fa()呼叫fb()

主調函式分配的記憶體,可以在被調函式中使用(指標做函式引數)

在fa(),fb()中分配的記憶體,如果實在棧區,不可在main()中呼叫,如果在堆區,全域性區,可以在main()中呼叫,注意記憶體的釋放問題

在被呼叫的函式中malloc的記憶體,首位址傳遞給呼叫函式有兩種方法

return

指標做函式引數

乙個單程序主程式有n個函式組成,c++編譯器只會分配乙個堆區,乙個棧區

棧(stack):向下生長

堆(heap):向上生長

heap、stack生長方向和記憶體存放方向是兩個不同概念

深入理解C Four 記憶體四區全域性區剖析

我們今天來剖析一下c語言的全域性區,我們上一節已經對棧區進行啦剖析.1.0 棧區作用 由編譯器自動分配釋放,存放函式的引數值和區域性變數的值。1.1全域性區作用 全域性變數和靜態變數的放在一塊的,初始化的全域性變數和靜態變數放在一塊區域 未初始化的全域性變數和未初始化的靜態變數在相鄰的另乙個區域,該...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...