(C語言課件) 動態(tài)存儲空間管理與鏈表_第1頁
(C語言課件) 動態(tài)存儲空間管理與鏈表_第2頁
(C語言課件) 動態(tài)存儲空間管理與鏈表_第3頁
(C語言課件) 動態(tài)存儲空間管理與鏈表_第4頁
(C語言課件) 動態(tài)存儲空間管理與鏈表_第5頁
已閱讀5頁,還剩46頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、2022-1-21第十七第十七 章章動態(tài)存儲空間管理與動態(tài)存儲空間管理與鏈表鏈表2022-1-22一、動態(tài)存儲分配及常見函數(shù)說明隱式和顯式北京交通大學計算機與信息技術學院教師:林友芳32022-1-21. 引例n要處理學生成績,需要用數(shù)組存放。但編程時并不知道運行時需要處理多少學生成績,每次處理的成績項數(shù)也可能不同。nint n;n.nscanf(%d, &n);ndouble scoresn; /* 不行!*/n. /* 讀入數(shù)據(jù),然后處理 */n不能用變量說明scores大?。ū仨氺o態(tài)確定)。北京交通大學計算機與信息技術學院教師:林友芳42022-1-22. 問題的本質(zhì)及解決方案n

2、問題的本質(zhì)n程序運行中需要使用存儲,有時程序對存儲的需求量在寫程序時不能確定。n可能解決方案1)分析問題,定義適當大小的數(shù)組。若分析正確,一般都能處理。但數(shù)據(jù)很多時程序就不能用。2)定義盡可能大的數(shù)組以滿足任何需要。浪費大量存儲資源。如有多個這種數(shù)組就更難辦。系統(tǒng)可能無法容納幾個大數(shù)組,但實際上它們并不同時需要很大空間。n解決的辦法是“動態(tài)存儲分配”。在程序運行中做存儲分配工作。北京交通大學計算機與信息技術學院教師:林友芳52022-1-23. 動態(tài)存儲分配n動態(tài)存儲分配n根據(jù)運行中的需要分配存儲,取得存儲塊使用,稱為動態(tài)存儲分配。在運行中根據(jù)需要動態(tài)進行。n動態(tài)存儲塊具有起始地址,地址可以存

3、儲在指針里,因此可以借助于指針保存存儲空間地址。n用指針指向存儲塊,間接使用被指存儲。訪問動態(tài)分配存儲是指針的最重要用途。北京交通大學計算機與信息技術學院教師:林友芳62022-1-24. 動態(tài)存儲釋放及存儲堆n動態(tài)釋放n不用的動態(tài)存儲塊應交還系統(tǒng),動態(tài)申請的內(nèi)存空間必須由程序代碼以顯式的方式主動釋放。n動態(tài)分配、釋放由動態(tài)存儲管理系統(tǒng)完成,這是程序運行系統(tǒng)的子系統(tǒng),管理著稱作堆(英文heap)的存儲區(qū)。n大部分常規(guī)語言都有這種機制。北京交通大學計算機與信息技術學院教師:林友芳72022-1-25. C語言的動態(tài)存儲管理機制n用標準庫函數(shù)實現(xiàn)用標準庫函數(shù)實現(xiàn)nstdlib.hstdlib.hn

4、malloc.hmalloc.hn存儲分配函數(shù)存儲分配函數(shù)mallocmalloc() (),原型:,原型:nvoid void * *malloc(size_tmalloc(size_t n); / n); /* *size_tsize_t是某整型是某整型* */ /n功能功能n分配一塊不小于分配一塊不小于n n的存儲,返回其地址。無法的存儲,返回其地址。無法滿足時返回空指針值。滿足時返回空指針值。北京交通大學計算機與信息技術學院教師:林友芳82022-1-2例intint n; double n; double * *data;data;. scanf(%d. scanf(%d, &

5、;n);, &n);data=(doubledata=(double* *)malloc(n)malloc(n* *sizeof(doublesizeof(double););if (data = NULL) if (data = NULL) . / . /* * 分配未完成時的處理分配未完成時的處理 * */ / .datai.datai.* *(data+j(data+j)./)./* *正常處理正常處理* */ /北京交通大學計算機與信息技術學院教師:林友芳92022-1-2malloc說明nmalloc使用注意事項:n的返回值(void*)應通過類型強制轉為特定指針類型后賦給指

6、針變量。n分配存儲塊大小應該用sizeof計算n動態(tài)分配必須檢查成功與否n動態(tài)分配的塊大小也是確定的。越界使用(尤其是越界賦值)是嚴重錯誤,可能導致程序或系統(tǒng)垮臺北京交通大學計算機與信息技術學院教師:林友芳102022-1-26. callocn帶計數(shù)和清帶計數(shù)和清0 0的存儲分配函數(shù)的存儲分配函數(shù)calloccalloc,原型:,原型:nvoid void * *calloc(size_tcalloc(size_t n, size_t size); n, size_t size);nsizesize是元素大小,是元素大小,n n是個數(shù)。是個數(shù)。n分配一塊存儲,足夠存分配一塊存儲,足夠存n n

7、個大小為個大小為sizesize的元素,并的元素,并把元素把元素全部清全部清0 0;n無法分配時返回空指針值。前面的存儲分配問題無法分配時返回空指針值。前面的存儲分配問題也可用下面語句實現(xiàn)也可用下面語句實現(xiàn)ndata = (doubledata = (double* *)calloc(n, sizeof(double)calloc(n, sizeof(double););n主要差別主要差別nmallocmalloc對所分配的區(qū)域不做任何事情,對所分配的區(qū)域不做任何事情,calloccalloc對整個區(qū)對整個區(qū)域自動清域自動清0 0。北京交通大學計算機與信息技術學院教師:林友芳112022-1-

8、27. 空間釋放函數(shù):freen為保證動態(tài)存儲的有效使用,動態(tài)分配塊不再用時應釋放。動態(tài)存儲塊的釋放只能通過調(diào)用free完成。Memory leakn函數(shù)原型nvoid free(void *p);n功能nfree釋放p指的存儲塊。n注意n該塊必須是通過動態(tài)存儲分配得到的,不要對并非指向動態(tài)分配塊的指針用本操作np值為空時什么也不做n執(zhí)行free(p)后p值未變,被指塊可能已變。不允許再間接訪問已釋放存儲塊北京交通大學計算機與信息技術學院教師:林友芳122022-1-28. 8. 分配調(diào)整函數(shù)分配調(diào)整函數(shù)reallocn函數(shù)原型nvoid *realloc(void *p, size_t n)

9、;n功能n更改已有分配。p指原分配塊,n是新大小要求。n返回大小至少為n的存儲塊指針,新塊與原塊一致:n新塊小時保存原塊n范圍內(nèi)數(shù)據(jù);n新塊大時原數(shù)據(jù)存在,新增部分不初始化。分配成功后原塊可能改變。n無法滿足時返回空指針,原塊不變。n常用寫法(防止分配失敗導致原存儲塊丟失) :nq = (double*)realloc(p, m * sizeof(double);nif (q = NULL) /*未成功,p仍指原塊,特殊處理*/ nelse p = q; /* 令p指向新塊,正常處理 */ .2022-1-213二、動態(tài)存儲空間管理如果動態(tài)申請了許多同類型緩沖區(qū),該如何管理?北京交通大學計算機

10、與信息技術學院教師:林友芳142022-1-2方法1:指針數(shù)組(地址數(shù)組)n設置一段內(nèi)存空間,例如數(shù)組,用來保存存儲空間的起始地址。n數(shù)組中每個元素用來保存某種類型的存儲空間的地址,等于每個元素都是一個指針變量。nint *pnarr10; /定義一個長度為10的整型指針數(shù)組(整型地址數(shù)組)nchar *psz5; /定義一個長度為5的字符指針數(shù)組。0 x0012ff7d0 x0012ff800 x0012fe12其中每個元素都用來保存某種類型的存儲空間的地址北京交通大學計算機與信息技術學院教師:林友芳152022-1-2例如n設一個班最多有50人,但每個班的人數(shù)不定,為了表示這50用戶,可以

11、定義如下指針數(shù)組nstruct UserAccount *Accounts 50;n完成如下功能n初始化指針數(shù)組n將新生成的某個班用戶加入班級用戶集,并存放在空位置上。n將某個班指定用戶號的用戶刪除n給某個班所有女生發(fā)m元補助n將新生成的某個班用戶插入到指定位置i上,i后面的用戶順序往后退。北京交通大學計算機與信息技術學院教師:林友芳162022-1-2指針數(shù)組結構示例0 x0012ff6dNULL0 x0012ff800 x0012ce000 x0012fe1208120001 張帥帥110108M0.1008120099 李美美350108F500.0008120002 趙小飛360108

12、M20.0008120007 羅小花410108F88.200 x0012ff6d0 x0012ff800 x0012ce000 x0012fe12長度為50空指針,可能曾被刪除后續(xù)元素或空或不空Accounts北京交通大學計算機與信息技術學院教師:林友芳172022-1-2功能實現(xiàn)n初始化指針數(shù)組void InitAccounts(struct UserAccount *Accounts, int nLen) for (int i = 0; i nLen; i+) Accountsi = NULL;n尋找一個空位置返回,-1表示無空位置int FindEmptyPlace(struct Us

13、erAccount *Accounts, int nLen) /可以有不同的搜索策略NULLNULL北京交通大學計算機與信息技術學院教師:林友芳182022-1-2功能實現(xiàn)(續(xù))n將新用戶放在空位置上,不成功返回-1,成功返回位置號int AddNewAccountAtAnyEmptyPlace(struct UserAccount *Accounts, int nLen, struct UserAccount *pUser) int nPlace;if (nPlace = FindEmptyPlace(Accounts, nLen) = -1) return -1; AccountsnPla

14、ce = pUser; /完成放置操作 return nPlace; /返回位置北京交通大學計算機與信息技術學院教師:林友芳192022-1-2功能示例0 x0012ff6dNULL0 x0012ff800 x0012ce000 x0012fe1208120001 張帥帥110108M0.1008120099 李美美350108F500.0008120002 趙小飛360108M20.0008120007 羅小花410108F88.200 x0012ff6d0 x0012ff800 x0012ce000 x0012fe12長度為50Accounts08120100 孫悟空110105M600.

15、100 x0012ff300 x0012ff30新找到的空位新結點孫悟空報到北京交通大學計算機與信息技術學院教師:林友芳202022-1-2功能實現(xiàn)(續(xù))n將指定用戶號的用戶刪除,返回該用戶原來所在位置int DeleteAccountByNumber(struct UserAccount *Accounts, int nLen, char *pszUserNO) int i; for (i = 0; i szUserNO) = 0) free(Accountsi); /釋放空間 Accountsi = NULL; /將當前位置置空 return i; return -1;用戶結構體指針數(shù)組數(shù)

16、組長度用戶號字符串比較函數(shù)北京交通大學計算機與信息技術學院教師:林友芳212022-1-2刪除功能示例0 x0012ff6d0 x0012ff300 x0012ff800 x0012ce000 x0012fe1208120001 張帥帥110108M0.1008120099 李美美350108F500.0008120002 趙小飛360108M20.0008120007 羅小花410108F88.200 x0012ff6d0 x0012ff800 x0012ce000 x0012fe12Accounts08120100 孫悟空110105M600.100 x0012ff30NULL把孫悟空位置

17、找到把孫悟空開除:DeleteAccountByNumber(Accounts, 50, “08120100”)釋放存儲空間北京交通大學計算機與信息技術學院教師:林友芳222022-1-2功能實現(xiàn)(續(xù))n給指定性別的群體充值,返回充值人數(shù)int ChargeByGender(struct UserAccount *Accounts, int nLen, char cGender, double dAmount) int nCounter = 0; /計數(shù)器 for (int i = 0; i cGender = cGender) Accountsi-dBalance+= dAmount; nC

18、ounter+; return nCounter;ChargeByGender(Accounts, 50, F, 10.0);/婦女節(jié)發(fā)補助北京交通大學計算機與信息技術學院教師:林友芳232022-1-2方法2:鏈接結構n采用鏈式數(shù)據(jù)結構n一環(huán)扣一扣,通過一個元素保存的其它元素的地址找到其它元素。n通過鏈接結構實現(xiàn)動態(tài)數(shù)據(jù)n增加元素:在鐵鏈的某個位置加一鐵環(huán)n刪除元素:去掉鐵鏈的某一鐵環(huán)n問題n鐵鏈中的每一鐵環(huán)是一樣的嗎?n普通的鐵鏈是單向的還是雙向的?n有沒有一些特殊的鐵鏈,比如有多個分叉的?n鐵鏈可以跟銅鏈拴一起嗎?n鐵鏈的頭部可以拴在柱子上嗎?北京交通大學計算機與信息技術學院教師:林友芳

19、242022-1-2鏈接結構實現(xiàn)原理n鏈接結構中的元素需要保存的信息n與結點本身有關的信息n找到其它元素所需要的信息n這些信息可以組織成結構n問題:如何找到其它元素?n保存其它元素在內(nèi)存中的地址n在結構中設置指針分量,用來保存其它元素的地址的分量指針分量n問題:指針的類型?n需要指向元素的結構類型的指針類型n如果需要指向的元素與本元素的類型相同的話,則需要定義自引用的結構類型。北京交通大學計算機與信息技術學院教師:林友芳252022-1-2鏈接結構n一個結構元素可以通過指針引用同類或不同類的結構元素,多個結構元素通過指針建立聯(lián)系。n指向結構的指針稱為鏈接,形成的復雜數(shù)據(jù)結構稱為鏈接結構n最簡單

20、的鏈接結構n線性鏈接形成的表,鏈接表。n每個自引用結構有一個鏈接指針分量。北京交通大學計算機與信息技術學院教師:林友芳262022-1-2最簡單的鏈接結構:單向鏈表n單向鏈接表就像鏈條,自引用結構是鏈表中的一個鏈節(jié),稱為鏈表結點,結點間由指針連接形成整個結構。n所有結點(結構)由動態(tài)分配創(chuàng)建。n從指向表首結點的指針出發(fā),沿鏈接可順序訪問表中各結點。該指針代表整個表。通常把最后結點的指針置空表示結束。0北京交通大學計算機與信息技術學院教師:林友芳272022-1-200000000更復雜的引用鏈接結構北京交通大學計算機與信息技術學院教師:林友芳282022-1-2單向鏈表結構示例struct U

21、serAccount char UserNO15; char Name20; char ID19; char Gender; double Balance;struct UserAccount *pNextUser;用來保存下一個結點的地址此處改成如下形式是否可行,為什么?struct UserAccount NextUser;北京交通大學計算機與信息技術學院教師:林友芳292022-1-2普通單向鏈表示意圖08120001 張帥帥110108M0.1008120002 趙小飛360108M20.0008120007 羅小花410108F88.2008120099 李美美350108F500.

22、00NULLHeadTail2022-1-230三、鏈表北京交通大學計算機與信息技術學院教師:林友芳312022-1-21. 需求n設有某系統(tǒng)的用戶信息結構體,其中n用戶ID長度為10n用戶姓名長度不超過10n需要處理的用戶數(shù)據(jù)不定,n假設某程序需要以鏈表方式處理用戶的數(shù)據(jù)北京交通大學計算機與信息技術學院教師:林友芳322022-1-2普通單向鏈表示意DataDataDataDataNULLHeadTail北京交通大學計算機與信息技術學院教師:林友芳332022-1-2鏈表結點結構聲明方法1:struct UserInfoNodechar szID11;/IDchar szName11;/姓名

23、 struct UserInfoNode *pNextUser; /下個用戶指針;方法2:typedef struct UserInfoNode USERNODE, *USERPOINTER;struct UserInfoNodechar szID11;/IDchar szName11;/姓名 USERPOINTER *pNextUser;/下個用戶指針;北京交通大學計算機與信息技術學院教師:林友芳342022-1-2更好的方法:基本信息單獨說明/用戶基本信息結構聲明struct UserInfochar szID11;/ID,11個字符個字符char szName11;/姓名,姓名,11個字

24、符個字符;或typedef structchar szID11;/ID,11個字符個字符char szName11;/姓名,姓名,11個字符個字符 USERINFO;北京交通大學計算機與信息技術學院教師:林友芳352022-1-2更常見合理的聲明方法方法3:struct UserLinkNode struct UserInfo Data;/數(shù)據(jù)數(shù)據(jù) struct UserLinkNode *pNextUser; /;struct UserInfo UserInfoArr100;或typedef struct USERINFO Data;/數(shù)據(jù)結點數(shù)據(jù)結點 struct UserLinkNode

25、 *pNextUser; / USERLINKNODE ;北京交通大學計算機與信息技術學院教師:林友芳362022-1-2增加一個鏈表描述信息結點NumberHeadTailDataDataDataDataNULLLinkInfoNoden關于鏈表整體描述信息結點北京交通大學計算機與信息技術學院教師:林友芳372022-1-2描述結點結構說明示例struct UserLinkstruct UserLinkNode *pHead; /頭指針頭指針 struct UserLinkNode *pTail; /尾指針尾指針int nNumber;/鏈表中的結點計數(shù)鏈表中的結點計數(shù);或typedef s

26、truct USERLINKNODE *pHead; /頭指針頭指針 USERLINKNODE *pTail; /尾指針尾指針int nNumber;/鏈表中的結點計數(shù)鏈表中的結點計數(shù) USERLINK;北京交通大學計算機與信息技術學院教師:林友芳382022-1-2可以增加一個不用的頭結點NumberHeadTailDataDataDataNULLLinkInfoNoden目的在于寫程序方便,簡化一些鏈表操作,數(shù)據(jù)結構課程中會有進一步的闡述不用的不用的頭結點頭結點北京交通大學計算機與信息技術學院教師:林友芳392022-1-2關于后面的操作的假定n鏈表為單向鏈表n沒有設置空的頭結點n設置有信

27、息描述結點,記錄如下信息n頭結點n尾結點n鏈表中結點個數(shù)北京交通大學計算機與信息技術學院教師:林友芳402022-1-2在鏈表中增加一個節(jié)點n有幾種增加方式n將新結點作為最后一個元素增加到鏈表的尾部,n將新結點作為第一個元素增加到鏈表的頭部n將新結點按照某種次序要求插入到指定位置北京交通大學計算機與信息技術學院教師:林友芳412022-1-2加到尾部n如果鏈表為空,則需要做一些初始化工作,將新的結點當成頭結點和尾結點n如果鏈表不為空,則將該結點作為尾結點的下一個結點,修改尾結點指針。n如果沒有記錄尾結點指針,則需要從頭結點開始找到最后一個結點。pHeadpTailDataDataNULLpNe

28、wNode NULL 北京交通大學計算機與信息技術學院教師:林友芳422022-1-2示例代碼,加到尾部int AddUserToTail( struct UserLink *pUsers, /鏈表描述信息指針 struct UserLinkNode *pNewUser/新結點指針) if (pUsers = NULL | pNewUser = NULL) return -1;if (pUsers-nNumber pHead = pNewUser; pUsers-pTail = pUsers-pHead; /頭尾指針指向同一個結點 else/把結點信息附到鏈表尾部 pUsers-pTail-p

29、Next = pNewUser; /加到尾到 pUsers-pTail = pNewUser;/修改尾結點指針 pUsers-pTail-pNext = NULL;/最后一個結點的后繼置空pUsers-nNumber+;/計數(shù)加1return 0;北京交通大學計算機與信息技術學院教師:林友芳432022-1-2加到頭部n如果鏈表為空,則需要做一些初始化工作,將新的結點當成頭結點和尾結點n如果鏈表不為空,需要將新結點的下一個結點置為原來的頭結點,并把新結點作為頭結點pHeadpTailDataDataNULLNULLpNewNode 北京交通大學計算機與信息技術學院教師:林友芳442022-1-

30、2示例代碼,加到頭部int AddUserToHead( struct UserLink *pUsers, /鏈表描述信息指針 struct UserLinkNode *pNewUser/新結點指針) if (pUsers = NULL | pNewUser = NULL) return -1;if (pUsers-nNumber pHead = pNewUser; pUsers-pTail = pUsers-pHead; /頭尾指針指向同一個結點 pNewUser-pNext = NULL; else/把結點信息附到鏈表頭部 pUsers-pNewUser-pNext = pUsers-pHead ; /加到頭部 pUsers-pHead = pNewUser;/修改頭結點指針 pUsers-nNumber+;/計數(shù)加1return 0;北京交通大學計算機與信息技術學院教師:林

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論