以下內容摘抄自 c語言程式設計 第9章:
根據馮諾依曼提出的「儲存原理」的計算機工作原理,程式要裝入記憶體後才能進行處理,資料也要裝入記憶體才能進行處理。
記憶體是以位元組為單位的一片連續儲存空間,每個位元組都有唯一的編號,這個編號稱為記憶體的「位址」。
如同人們通過房間號來管理旅館一樣,系統通過記憶體位址來對記憶體進行管理。
位址從0開始,順序依次編號,且位址用二進位制表示。(下面用十進位制來表述)
編譯系統根據變數的型別,為其分配一定位元組的儲存單元。如int i;
, 系統為變數i 分配4個位元組的儲存單元。
假定系統為變數i分配的4個位元組(1201~1204)如下圖所示,那麼變數 i 的記憶體位址就是1201(第乙個位元組的位址)。
一般情況下,程式設計師無需知道每個變數在記憶體中的具體位址,生成二進位制目標程式時,編譯系統將變數名轉換成了相應的記憶體位址。所以,程式通過變數名對變數的訪問,實際上是對某個位址儲存單元的訪問。(這種直接按記憶體位址訪問變數的方式稱為直接訪問)
下面的圖更清楚些,定義乙個變數時,系統會在記憶體中為變數分配一塊空間。
例如上面為int i;
變數i
分配4個位元組(1201~1204)的空間。i = 30;
,將30(實際是二進位制數)寫在這塊空間裡。
訪問變數i
時,就是訪問變數i
指向的記憶體位址儲存空間中的30
。
如果是課堂上,指標夠老師講兩個星期的。
上面是按照記憶體位址直接訪問變數。
c語言還提供了一種間接訪問。即將要訪問的變數的位址存在乙個指標變數中。,訪問時先從指標變數中取出位址值,然後根據位址值去訪問對應的儲存單元。看下面幾行**
int i;
定義變數i,編譯時,系統為變數 i 分配4個位元組的儲存空間。
int *p;
定義指標變數p,系統為變數 p 分配4個位元組的儲存空間。
i = 30;
將30(0000…11110)寫到變數 i 對應的儲存空間裡。
p = &i
使用&取位址符將變數i對應的記憶體位址寫到變數 p 對應的儲存空間裡。
如下圖,假設變數i
(4個位元組)的記憶體位址為1201
,變數p
(4個位元組)的記憶體位址為2300
。
變數i
中儲存著乙個整數30
,指標變數p中儲存著變數i
的記憶體位址1201
。
間接訪問時,要先訪問指標變數,按照指標變數 儲存的位址值去訪問相應的儲存單元。這樣比起直接訪問,要費時間,且不直觀。但是,通過改變指標變數的值,即改變其指向,可訪問不同的變數,更加靈活,也使**更簡潔和有效。
首先,memory leak(記憶體洩漏)。
比如int x = malloc(40)
,請求系統為x分配40位元組的儲存空間。
(malloc,memory allocate)
如果這條語句在乙個普通函式中,不停地被呼叫,即不停請求分配40位元組的儲存空間。
系統記憶體會一直被占用,記憶體越來越少,即記憶體洩漏。
解決辦法是,每次請求分配儲存空間後,使用free()
釋放記憶體。
然後,stack overflow(堆疊溢位)(著名**)。
看下面的例子:
程式中請求為name
變數分配9個位元組的記憶體空間,即能儲存9個字元。
實際上輸入了fengweilei
10個字元,將fengweilei
寫入name
時,自然不夠寫。然後會被寫入記憶體中其他的地方,很容易造成**煩。
和stack overflow 類似的,還有heap overflow,buffer overflow。
最後,hexadecimal,十六進製制數(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f)。
255(1111 1111,0xff)
216(1101 1000,0xd8)
255(1111 1111,0xff)
用十六進製制數更方便,0x標誌16進製制數。
bmp格式,bmp檔案前幾個位元組會儲存影象高度、寬度,還能看到bmp基於rgb原理的資訊。
通過,jpg,bmp,過渡到了 data structure。
又是好難理解的一部分。
CS50 2016 Week 0 學習筆記
今天開始從第一課開始學習了。week 0 和大學裡許多的第一節課一樣,只是簡單介紹這門課,沒有太多乾貨。有幾個知識點,比較重要。機器語言,即計算機能直接理解的語言,只有0 和 1 二進位制數 通過字元編碼,能用不同的數字表示不同的字元,能用二進位制數來表示我們熟悉的字元。乙個位元組儲存8個二進位制數...
CS50 2016 Week 2 學習筆記
這一課先講了除錯程式 debug 然後講了 正確性 設計 風格,最後講了陣列的概念。核心思想是程式報錯後,能找到哪兒錯了,怎麼錯的。如果是語法錯誤,根據報錯資訊,大概能找到怎麼錯的。如果是邏輯錯誤,可以自己在腦海中過一遍程式執行的流程,看哪兒有邏輯錯誤,或者自己在可能有問題的地方寫測試 c語言軟體中...
CS50 2016 Week3 學習筆記
上一課講了陣列,這節課順利過渡到了陣列的查詢 排序。即查詢演算法 排序演算法。關於查詢演算法,除了常見的linear search binary search 還有好多好多。下面是常見的七大查詢演算法 順序查詢 二分查詢 插值查詢 斐波那契查詢 樹表查詢 分塊查詢 雜湊查詢 排序演算法,除了氣泡排序...