内存的使用
內(nèi)容整理于朱有鵬老師的課程。
1、馮諾依曼結(jié)構(gòu)和哈佛結(jié)構(gòu)
- 馮諾依曼結(jié)構(gòu)是數(shù)據(jù)和代碼放在一起,哈佛結(jié)構(gòu)是數(shù)據(jù)和代碼分開存在。
- 什么是代碼:函數(shù)。什么是數(shù)據(jù):全局變量、局部變量。
- 在S5PV210中運(yùn)行的linux系統(tǒng)上,運(yùn)行應(yīng)用程序時(shí),所有的應(yīng)用程序的代碼和數(shù)據(jù)都在DRAM,所以這種結(jié)構(gòu)就是馮諾依曼結(jié)構(gòu)。
- 在單片機(jī)中,程序代碼燒寫到Flash(NorFlash)中,然后程序在Flash中原地運(yùn)行,程序中所涉及到的數(shù)據(jù)(全局變量、局部變量)放在RAM(SRAM)中。這種就叫哈佛結(jié)構(gòu)。
2、動(dòng)態(tài)內(nèi)存DRAM和靜態(tài)內(nèi)存SRAM
- DRAM是動(dòng)態(tài)內(nèi)存,SRAM是靜態(tài)內(nèi)存。
3、為什么需要內(nèi)存
- 內(nèi)存是用來存儲(chǔ)可變數(shù)據(jù)的,數(shù)據(jù)在程序中表現(xiàn)為全局變量、局部變量等(在gcc中,其實(shí)常量也是存儲(chǔ)在內(nèi)存中的)(大部分單片機(jī)中,常量是存儲(chǔ)在flash中的,也就是在代碼段),對(duì)我們寫程序來說非常重要,對(duì)程序運(yùn)行更是本質(zhì)相關(guān)。所以內(nèi)存對(duì)程序來說幾乎是本質(zhì)需求。
4、如何管理內(nèi)存
(1)有無操作系統(tǒng)
- 有操作系統(tǒng):操作系統(tǒng)掌握所有的硬件內(nèi)存,因?yàn)閮?nèi)存很大,所以操作系統(tǒng)把內(nèi)存分成1個(gè)1個(gè)的頁(yè)面(其實(shí)就是一塊,一般是4KB),然后以頁(yè)面為單位來管理。頁(yè)面內(nèi)用更細(xì)小的方式來以字節(jié)為單位管理。操作系統(tǒng)內(nèi)存管理的原理非常麻煩、非常復(fù)雜、非常不人性化。操作系統(tǒng)給我們提供了內(nèi)存管理的一些接口,我們只需要用API即可管理內(nèi)存。譬如在C語言中使用malloc free這些接口來管理內(nèi)存。
- 無操作系統(tǒng)時(shí):裸機(jī)程序中,程序需要直接操作內(nèi)存,編程者需要自己計(jì)算內(nèi)存的使用和安排。
- 不同的語言提供了不同的操作內(nèi)存的接口。
- 譬如匯編根本沒有任何內(nèi)存管理,內(nèi)存管理全靠程序員自己,匯編中操作內(nèi)存時(shí)直接使用內(nèi)存地址(譬如0xd0020010),非常麻煩;
- 譬如C語言中編譯器管理直接內(nèi)存地址,我們都是通過編譯器提供的變量名等來訪問內(nèi)存的,操作系統(tǒng)下如果需要大塊內(nèi)存,可以通過API(malloc free)來訪問系統(tǒng)內(nèi)存。
- 譬如C++語言對(duì)內(nèi)存的使用進(jìn)一步封裝。我們可以用new來創(chuàng)建對(duì)象(其實(shí)就是為對(duì)象分配內(nèi)存),然后使用完了用delete來刪除對(duì)象(其實(shí)就是釋放內(nèi)存)。所以C++語言對(duì)內(nèi)存的管理比C要高級(jí)一些,容易一些。但是C++中內(nèi)存的管理還是靠程序員自己來做。如果程序員new了一個(gè)對(duì)象,但是用完了忘記delete就會(huì)造成這個(gè)對(duì)象占用的內(nèi)存不能釋放,這就是內(nèi)存泄漏。
- Java/C#等語言不直接操作內(nèi)存,而是通過虛擬機(jī)來操作內(nèi)存。這樣虛擬機(jī)作為我們程序員的代理,來幫我們處理內(nèi)存的釋放工作。如果程序申請(qǐng)了內(nèi)存,使用完成后忘記釋放,則虛擬機(jī)會(huì)釋放掉這些內(nèi)存。
5、位、字節(jié)、半字、字和內(nèi)存位寬
(1)什么是內(nèi)存?
- 從硬件角度:內(nèi)存是電腦的一個(gè)配件(內(nèi)存條)。根據(jù)不同的硬件實(shí)現(xiàn)原理又分成SRAM和DRAM(DRAM又有好多代,譬如最早的SDRAM,后來的DDR1……LPDDR)。
- 從邏輯角度:內(nèi)存可以隨機(jī)訪問(隨機(jī)訪問的意思是只要給一個(gè)地址,就可以訪問這個(gè)內(nèi)存地址),并且可以讀寫。內(nèi)存是用來存放變量的(因?yàn)橛辛藘?nèi)存,所以C語言中才能定義變量,C語言中的一個(gè)變量對(duì)應(yīng)內(nèi)存中的一個(gè)單元)。
- 邏輯上來說,內(nèi)存可以有無限大(因?yàn)閿?shù)學(xué)上編號(hào)永遠(yuǎn)可以增加,無盡頭)。但是實(shí)際的內(nèi)存大小是有限制的,譬如32位的系統(tǒng)(32位系統(tǒng)指的是32位數(shù)據(jù)線,但是一般地址線也是32位,這個(gè)地址線32位決定了內(nèi)存地址只能有32位二進(jìn)制,所以邏輯上的大小為2的32次方)內(nèi)存限制就為4G。
- 在所有的計(jì)算機(jī)、所有的機(jī)器中(不管是32位系統(tǒng)還是16位系統(tǒng)還是以后的64位系統(tǒng)),位永遠(yuǎn)都是1bit,字節(jié)永遠(yuǎn)都是8bit。
- 這些單位具體有多少位是依賴于平臺(tái)的。實(shí)際工作中在每種平臺(tái)上先去搞清楚這個(gè)平臺(tái)的定義(字是多少位,半字永遠(yuǎn)是字的一半,雙字永遠(yuǎn)是字的2倍大小)。
- 在linux+ARM這個(gè)軟硬件平臺(tái)上(我們嵌入式核心課的所有課程中),字是32位的。
- 從硬件角度講:硬件內(nèi)存的實(shí)現(xiàn)本身是有寬度的,即有些內(nèi)存條是8位的,有些是16位的。內(nèi)存芯片之間可以并聯(lián),通過并聯(lián)后即使8位的內(nèi)存芯片也可以做出來16位或32位的硬件內(nèi)存。
- 從邏輯角度講:內(nèi)存位寬在邏輯上是任意的,甚至邏輯上存在內(nèi)存位寬是24位的內(nèi)存(但是實(shí)際上這種硬件是買不到的,也沒有實(shí)際意義)。
6、內(nèi)存編址和尋址、內(nèi)存對(duì)齊
(1)內(nèi)存編址是以字節(jié)為單位的
(2)內(nèi)存和數(shù)據(jù)類型的關(guān)系
- C語言中的基本數(shù)據(jù)類型有:char short int long float double ;
- int 整形(整數(shù)類型,這個(gè)整就體現(xiàn)在它和CPU本身的數(shù)據(jù)位寬是一樣的)譬如32位的CPU,整形就是32位,int就是32位。
- 數(shù)據(jù)類型和內(nèi)存的關(guān)系就在于:數(shù)據(jù)類型是用來定義變量的,而這些變量需要存儲(chǔ)、運(yùn)算在內(nèi)存中。所以數(shù)據(jù)類型必須和內(nèi)存相匹配才能獲得最好的性能,否則可能不工作或者效率低下。在32位系統(tǒng)中定義變量最好用int,因?yàn)檫@樣效率高。原因就在于32位的系統(tǒng)本身配合內(nèi)存等也是32位,這樣的硬件配置天生適合定義32位的int類型變量,效率最高。也能定義8位的char類型變量或者16位的short類型變量,但是實(shí)際上訪問效率不高。在很多32位環(huán)境下,我們實(shí)際定義bool類型變量(實(shí)際只需要1個(gè)bit就夠了)都是用int來實(shí)現(xiàn)bool的。也就是說我們定義一個(gè)bool b1;時(shí),編譯器實(shí)際幫我們分配了32位的內(nèi)存來存儲(chǔ)這個(gè)bool變量b1。編譯器這么做實(shí)際上浪費(fèi)了31位的內(nèi)存,但是好處是效率高。
(3)內(nèi)存對(duì)齊
- 在C中int a;定義一個(gè)int類型變量,在內(nèi)存中就必須分配4個(gè)字節(jié)來存儲(chǔ)這個(gè)a。有這么2種不同內(nèi)存分配思路和策略:
- ? ? ?第一種:0 1 2 3 對(duì)齊訪問
- ? ? ?第二種:1 2 3 4?或者 2 3 4 5 或者 3 4 5 6 非對(duì)齊訪問
- 內(nèi)存的對(duì)齊訪問不是邏輯的問題,是硬件的問題。從硬件角度來說,32位的內(nèi)存它 0 1 2 3四個(gè)單元本身邏輯上就有相關(guān)性,這4個(gè)字節(jié)組合起來當(dāng)作一個(gè)int硬件上就是合適的,效率就高。對(duì)齊訪問很配合硬件,所以效率很高;非對(duì)齊訪問因?yàn)楹陀布旧聿淮钆?#xff0c;所以效率不高。(因?yàn)榧嫒菪缘膯栴},一般硬件也都提供非對(duì)齊訪問,但是效率要低很多。)
7、C語言如何操作內(nèi)存
(1)C語言對(duì)內(nèi)存地址的封裝
(用變量名來訪問內(nèi)存、數(shù)據(jù)類型的含義、函數(shù)名的含義)
-------------------------------------------------------------------------------------
譬如在C語言中 int a; a = 5; a += 4; // a == 9;
結(jié)合內(nèi)存來解析C語言語句的本質(zhì):
int a; // 編譯器幫我們申請(qǐng)了1個(gè)int類型的內(nèi)存格子(長(zhǎng)度是4字節(jié),地址是確定的,但是只有編譯器知道,我們是不知道的,也不需要知道。),并且把符號(hào)a和這個(gè)格子綁定。
a = 5; // 編譯器發(fā)現(xiàn)我們要給a賦值,就會(huì)把這個(gè)值5丟到符號(hào)a綁定的那個(gè)內(nèi)存格子中。
a += 4; // 編譯器發(fā)現(xiàn)我們要給a加值,a += 4 等效于 a = a + 4;編譯器會(huì)先把a(bǔ)原來的值讀出來,然后給這個(gè)值加4,再把加之后的和寫入a里面去。
C語言中數(shù)據(jù)類型的本質(zhì)含義是:表示一個(gè)內(nèi)存格子的長(zhǎng)度和解析方法。
數(shù)據(jù)類型決定長(zhǎng)度的含義:我們一個(gè)內(nèi)存地址(0x30000000),本來這個(gè)地址只代表1個(gè)字節(jié)的長(zhǎng)度,但是實(shí)際上我們可以通過給他一個(gè)類型(int),讓他有了長(zhǎng)度(4),這樣這個(gè)代表內(nèi)存地址的數(shù)字(0x30000000)就能表示從這個(gè)數(shù)字(0x30000000)開頭的連續(xù)的n(4)個(gè)字節(jié)的內(nèi)存格子了(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003)。
數(shù)據(jù)類型決定解析方法的含義:譬如我有一個(gè)內(nèi)存地址(0x30000000),我們可以通過給這個(gè)內(nèi)存地址不同的類型來指定這個(gè)內(nèi)存單元格子中二進(jìn)制數(shù)的解析方法。譬如我 (int)0x30000000,含義就是(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003)這4個(gè)字節(jié)連起來共同存儲(chǔ)的是一個(gè)int型數(shù)據(jù);那么我(float)0x30000000,含義就是(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003)這4個(gè)字節(jié)連起來共同存儲(chǔ)的是一個(gè)float型數(shù)據(jù);
之前講過一個(gè)很重要的概念:內(nèi)存單元格子的編址單位是字節(jié)。
(int *)0;
(float *)0;
(short)0;
(char)0;
int a; // int a;時(shí)編譯器會(huì)自動(dòng)給a分配一個(gè)內(nèi)存地址,譬如說是0x12345678
(int *)a; // 等價(jià)于(int *)0x12345678
(float *)a;
C語言中,函數(shù)就是一段代碼的封裝。函數(shù)名的實(shí)質(zhì)就是這一段代碼的首地址。所以說函數(shù)名的本質(zhì)也是一個(gè)內(nèi)存地址。
------------------------------------------------------------------------------------------------------
(2)用指針來間接訪問內(nèi)存
- 類型只是對(duì)后面數(shù)字或者符號(hào)(代表的是內(nèi)存地址)所表征的內(nèi)存的一種長(zhǎng)度規(guī)定和解析方法規(guī)定而已。
- C語言中的指針,全名叫指針變量,指針變量其實(shí)很普通變量沒有任何區(qū)別。譬如int a和int *p其實(shí)沒有任何區(qū)別,a和p都代表一個(gè)內(nèi)存地址(譬如是0x20000000),但是這個(gè)內(nèi)存地址(0x20000000)的長(zhǎng)度和解析方法不同。a是int型所以a的長(zhǎng)度是4字節(jié),解析方法是按照int的規(guī)定來的;p是int *類型,所以長(zhǎng)度是4字節(jié),解析方法是int *的規(guī)定來的(0x20000000開頭的連續(xù)4字節(jié)中存儲(chǔ)了1個(gè)地址,這個(gè)地址所代表的內(nèi)存單元中存放的是一個(gè)int類型的數(shù))。
(3)用數(shù)組來管理內(nèi)存
- 數(shù)組管理內(nèi)存和變量其實(shí)沒有本質(zhì)區(qū)別,只是符號(hào)的解析方法不同。(普通變量、數(shù)組、指針變量其實(shí)都沒有本質(zhì)差別,都是對(duì)內(nèi)存地址的解析,只是解析方法不一樣)。
- int a; // 編譯器分配4字節(jié)長(zhǎng)度給a,并且把首地址和符號(hào)a綁定起來。
- int b[10]; // 編譯器分配40個(gè)字節(jié)長(zhǎng)度給b,并且把首元素首地址和符號(hào)b綁定起來。數(shù)組中第一個(gè)元素(b[0])就稱為首元素;每一個(gè)元素類型都是int,所以長(zhǎng)度都是4,其中第一個(gè)字節(jié)的地址就稱為首地址;首元素b[0]的首地址就稱為首元素首地址。
8、內(nèi)存管理之結(jié)構(gòu)體
(1)數(shù)組的優(yōu)勢(shì)和缺陷
- 優(yōu)勢(shì):數(shù)組比較簡(jiǎn)單,訪問用下標(biāo),可以隨機(jī)訪問。
- 缺陷:1 數(shù)組中所有元素類型必須相同;2 數(shù)組大小必須定義時(shí)給出,而且一旦確定不能再改。
- 結(jié)構(gòu)體發(fā)明出來就是為了解決數(shù)組的第一個(gè)缺陷:數(shù)組中所有元素類型必須相同
- C語言是面向過程的,但是C語言寫出的linux系統(tǒng)是面向?qū)ο蟮摹?/span>
- 非面向?qū)ο蟮恼Z言,不一定不能實(shí)現(xiàn)面向?qū)ο蟮拇a。只是說用面向?qū)ο蟮恼Z言來實(shí)現(xiàn)面向?qū)ο笠雍?jiǎn)單一些、直觀一些。用C++、Java等面向?qū)ο蟮恼Z言來實(shí)現(xiàn)面向?qū)ο蠛?jiǎn)單一些,因?yàn)檎Z言本身幫我們做了很多事情
struct s {int age; // 普通變量void (*pFunc)(void); // 函數(shù)指針,指向 void func(void)這類的函數(shù) };//使用這樣的結(jié)構(gòu)體就可以實(shí)現(xiàn)面向?qū)ο蟆?//這樣包含了函數(shù)指針的結(jié)構(gòu)體就類似于面向?qū)ο笾械腸lass ///結(jié)構(gòu)體中的變量類似于class中的成員變量,結(jié)構(gòu)體中的函數(shù)指針類似于class中的成員方法。
9、內(nèi)存管理之棧(stack)
(1)什么是棧
- 棧是一種數(shù)據(jù)結(jié)構(gòu),C語言中使用棧來保存局部變量。棧是被發(fā)明出來管理內(nèi)存的。
(2)棧管理內(nèi)存的特點(diǎn)(小內(nèi)存、自動(dòng)化)
- 先進(jìn)后出 FILO:first in last out,棧;
- 先進(jìn)先出 FIFO:first in first out,隊(duì)列;
- C語言中的局部變量是用棧來實(shí)現(xiàn)的。
- 我們?cè)贑中定義一個(gè)局部變量時(shí)(int a),編譯器會(huì)在棧中分配一段空間(4字節(jié))給這個(gè)局部變量用(分配時(shí)棧頂指針會(huì)移動(dòng)給出空間,給局部變量a用的意思就是,將這4字節(jié)的棧內(nèi)存的內(nèi)存地址和我們定義的局部變量名a給關(guān)聯(lián)起來),對(duì)應(yīng)棧的操作是入棧。函數(shù)退出的時(shí)候,局部變量要滅亡,對(duì)應(yīng)棧的操作是彈棧(出棧)。出棧時(shí)也是棧頂指針移動(dòng)將棧空間中與a關(guān)聯(lián)的那4個(gè)字節(jié)空間釋放。
- 注意這里棧指針的移動(dòng)和內(nèi)存分配是自動(dòng)的(棧自己完成,不用我們寫代碼去操作)。
(4)棧的優(yōu)點(diǎn)
- 好處是方便,分配和最后回收都不用程序員操心,C語言自動(dòng)完成。
- C語言中,定義局部變量時(shí)如果未初始化,則值是隨機(jī)的,為什么?定義局部變量,其實(shí)就是在棧中通過移動(dòng)棧指針來給程序提供一個(gè)內(nèi)存空間和這個(gè)局部變量名綁定。因?yàn)檫@段內(nèi)存空間在棧上,而棧內(nèi)存是反復(fù)使用的(臟的,上次用完沒清零的),所以說使用棧來實(shí)現(xiàn)的局部變量定義時(shí)如果不顯式初始化,值就是臟的。
- 如果你顯式初始化怎么樣?C語言是通過一個(gè)小手段來實(shí)現(xiàn)局部變量的初始化的,即:
- int a = 15;// 局部變量定義時(shí)初始化
- C語言編譯器會(huì)自動(dòng)把這行轉(zhuǎn)成:i
- nt a;// 局部變量定義
- a = 15;// 普通的賦值語句
- 棧是有大小的。所以棧內(nèi)存大小不好設(shè)置。如果太小怕溢出,太大怕浪費(fèi)內(nèi)存。(這個(gè)缺點(diǎn)有點(diǎn)像數(shù)組);
- 棧的溢出危害很大,一定要避免。
- 我們?cè)贑語言中定義局部變量時(shí)不能定義太多或者太大(譬如不能定義局部變量時(shí) int a[10000]; 使用遞歸來解決問題時(shí)一定要注意遞歸收斂)
10、內(nèi)存管理之堆
(1)什么是堆- 堆(heap)是一種內(nèi)存管理方式。
- 內(nèi)存管理對(duì)操作系統(tǒng)來說是一件非常復(fù)雜的事情,因?yàn)槭紫葍?nèi)存容量很大,其次內(nèi)存需求在時(shí)間和大小塊上沒有規(guī)律(操作系統(tǒng)上運(yùn)行著的幾十、幾百、幾千個(gè)進(jìn)程隨時(shí)都會(huì)申請(qǐng)或者釋放內(nèi)存,申請(qǐng)或者釋放的內(nèi)存塊大小隨意)。
- 堆這種內(nèi)存管理方式特點(diǎn)就是自由(隨時(shí)申請(qǐng)、釋放;大小塊隨意)。
- 堆內(nèi)存是操作系統(tǒng)劃歸給堆管理器(操作系統(tǒng)中的一段代碼,屬于操作系統(tǒng)的內(nèi)存管理單元)來管理的,然后向使用者(用戶進(jìn)程)提供API(malloc和free)來使用堆內(nèi)存。
- 什么時(shí)候使用堆內(nèi)存?需要內(nèi)存容量比較大時(shí),需要反復(fù)使用及釋放時(shí),很多數(shù)據(jù)結(jié)構(gòu)(譬如鏈表)的實(shí)現(xiàn)都要使用堆內(nèi)存。
(2)堆管理內(nèi)存的特點(diǎn)
- 特點(diǎn)一:容量不限(常規(guī)使用的需求容量都能滿足)。
- 特點(diǎn)二:申請(qǐng)及釋放都需要手工進(jìn)行,手工進(jìn)行的含義就是需要程序員寫代碼明確進(jìn)行申請(qǐng)malloc及釋放free。如果程序員申請(qǐng)內(nèi)存并使用后未釋放,這段內(nèi)存就丟失了(在堆管理器的記錄中,這段內(nèi)存仍然屬于你這個(gè)進(jìn)程,但是進(jìn)程自己又以為這段內(nèi)存已經(jīng)不用了,再用的時(shí)候又會(huì)去申請(qǐng)新的內(nèi)存塊,這就叫吃內(nèi)存),稱為內(nèi)存泄漏。在C/C++語言中,內(nèi)存泄漏是最嚴(yán)重的程序bug,這也是別人認(rèn)為Java/C#等語言比C/C++優(yōu)秀的地方。
(3)C語言操作堆內(nèi)存的接口(malloc free)
- 堆內(nèi)存釋放時(shí)最簡(jiǎn)單,直接調(diào)用free釋放即可。void free(void *ptr);
- 堆內(nèi)存申請(qǐng)時(shí),有3個(gè)可選擇的類似功能的函數(shù):malloc, calloc, realloc
- 數(shù)組定義時(shí)必須同時(shí)給出數(shù)組元素個(gè)數(shù)(數(shù)組大小),而且一旦定義再無法更改。在Java等高級(jí)語言中,有一些語法技巧可以更改數(shù)組大小,但其實(shí)這只是一種障眼法。它的工作原理是:先重新創(chuàng)建一個(gè)新的數(shù)組大小為要更改后的數(shù)組,然后將原數(shù)組的所有元素復(fù)制進(jìn)新的數(shù)組,然后釋放掉原數(shù)組,最后返回新的數(shù)組給用戶.
- 堆內(nèi)存申請(qǐng)時(shí)必須給定大小,然后一旦申請(qǐng)完成大小不變,如果要變只能通過realloc接口。realloc的實(shí)現(xiàn)原理類似于上面說的Java中的可變大小的數(shù)組的方式。
- 管理大塊內(nèi)存、靈活、容易內(nèi)存泄漏。
11、復(fù)雜數(shù)據(jù)結(jié)構(gòu)
(1)鏈表、哈希表、二叉樹、圖等
- 鏈表在linux內(nèi)核中使用非常多,驅(qū)動(dòng)、應(yīng)用編寫很多時(shí)候都需要使用鏈表。所以對(duì)鏈表必須掌握,掌握到:會(huì)自己定義結(jié)構(gòu)體來實(shí)現(xiàn)鏈表、會(huì)寫鏈表的節(jié)點(diǎn)插入(前插、后插)、節(jié)點(diǎn)刪除、節(jié)點(diǎn)查找、節(jié)點(diǎn)遍歷等。(至于像逆序這些很少用,掌握了前面那幾個(gè)這個(gè)也不難)。
- 哈希表不是很常用,一般不需要自己寫實(shí)現(xiàn),而直接使用別人實(shí)現(xiàn)的哈希表比較多。對(duì)我們來說最重要的是要明白哈希表的原理、從而知道哈希表的特點(diǎn),從而知道什么時(shí)候該用哈希表,當(dāng)看到別人用了哈希表的時(shí)候要明白別人為什么要用哈希表、合適不合適?有沒有更好的選擇?
- 二叉樹、圖等。對(duì)于這些復(fù)雜數(shù)據(jù)結(jié)構(gòu),不要太當(dāng)回事。這些復(fù)雜數(shù)據(jù)結(jié)構(gòu)用到的概率很小(在嵌入式開發(fā)中),其實(shí)這些數(shù)據(jù)結(jié)構(gòu)被發(fā)明出來就是為了解決特定問題的,你不處理特定問題根本用不到這些,沒必要去研究。
- 在實(shí)際應(yīng)用中,實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和算法的人和使用數(shù)據(jù)結(jié)構(gòu)和算法的人是分開的。實(shí)際中有一部分人的工作就是研究數(shù)據(jù)結(jié)構(gòu)和算法,并且試圖用代碼來實(shí)現(xiàn)這些算法(表現(xiàn)為庫(kù));其他做真正工作的人要做的就是理解、明白這些算法和數(shù)據(jù)結(jié)構(gòu)的意義、優(yōu)劣、特征,然后在合適的時(shí)候選擇合適的數(shù)據(jù)結(jié)構(gòu)和算法來解決自己碰到的實(shí)際問題。
總結(jié)
- 上一篇: java嵌入浏览器_Java嵌入浏览器C
- 下一篇: Keil芯片安装包下载