當陣列做函式引數的時候,會退化為乙個指標
此時在函式內是得不到陣列大小的
因此,陣列做函式引數的時候需要傳遞陣列大小,也就是多傳遞乙個引數
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 + 1
和a + 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操作記憶體 在指標宣告時,號表示所宣告的變數為指...