CS50 2016 Week4 學習筆記

2021-08-07 22:45:08 字數 2565 閱讀 6360

以下內容摘抄自 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個字元。

實際上輸入了fengweilei10個字元,將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 還有好多好多。下面是常見的七大查詢演算法 順序查詢 二分查詢 插值查詢 斐波那契查詢 樹表查詢 分塊查詢 雜湊查詢 排序演算法,除了氣泡排序...