別再說你的單片機(jī)RAM不夠用了,來看看這個(gè)吧...
當(dāng)我們寫代碼的時(shí)候,會(huì)用到很多變量,如果隨意的定義變量,比如寫了N多個(gè)“unsigned char/int X;”那么代碼可能會(huì)顯的很亂,自己拐回頭看的時(shí)候都暈掉了,那么這個(gè)時(shí)候我們可以構(gòu)造一個(gè)復(fù)雜的數(shù)據(jù)類型-結(jié)構(gòu)體類型,對(duì)代碼中出現(xiàn)的變量進(jìn)行類別的劃分,用構(gòu)造的結(jié)構(gòu)體類型定義結(jié)構(gòu)體變量,在寫or看代碼的時(shí)候,只要看到這個(gè)結(jié)構(gòu)體,就能大致的知道其實(shí)現(xiàn)功能,這樣看起來就神清氣爽了,可讀性大大提高。
我們定義的結(jié)構(gòu)體變量,如果沒有特殊規(guī)定的話是存儲(chǔ)在RAM中的,單片機(jī)的RAM資源是有限的,那這個(gè)結(jié)構(gòu)體變量在RAM中占的空間大小就是我們需要關(guān)注一個(gè)問題了,它真的像你想的那么“單純”嗎?接下來我們一起來看看吧!
在看下面的圖之前,我們說一個(gè)前提,在STM32單片機(jī)這個(gè)32位系統(tǒng)中,signed/unsigned int 占4個(gè)字節(jié),signed/unsigned short int 占2個(gè)字節(jié) signed/unsigned char 占1個(gè)字節(jié),我們稱這些為基本數(shù)據(jù)類型。Size = Sizeof(Test);這個(gè)函數(shù)是求取這個(gè)結(jié)構(gòu)體變量Test所占內(nèi)存的大小,并返回給Size。
圖1
圖2
請(qǐng)看上圖,我們使用基本數(shù)據(jù)類型構(gòu)造了3個(gè)復(fù)雜的結(jié)構(gòu)體數(shù)據(jù)類型,仔細(xì)看會(huì)發(fā)現(xiàn),這3個(gè)數(shù)據(jù)類型的成員可是不大一樣的,我們來看第一個(gè)Test,這個(gè)數(shù)據(jù)類型總共占4+4=8個(gè)字節(jié),這個(gè)很好理解,那第二個(gè)Test1,占空間大小按道理來說應(yīng)該是1+4 = 5個(gè)字節(jié),但是為什么還是8呢,第三個(gè)Test2,占空間大小應(yīng)該是1+1+4=8,為什么還是8呢?
這個(gè)里面就涉及到了結(jié)構(gòu)體對(duì)齊,所有的成員在分配內(nèi)存時(shí)都要與所有成員中占內(nèi)存最多的基本數(shù)據(jù)類型所占內(nèi)存空間的字節(jié)數(shù)對(duì)齊。假如這個(gè)字節(jié)數(shù)為N,那么對(duì)齊的原則是:理論上所有成員在分配內(nèi)存時(shí)都是緊接在前一個(gè)變量后面依次填充的,但是如果是“以 N 對(duì)齊”為原則,那么,如果一行中剩下的空間不足以填充某成員變量時(shí),即剩下的空間小于某成員變量的數(shù)據(jù)類型所占的字節(jié)數(shù),該成員變量在分配內(nèi)存時(shí)另起一行分配。如圖3,4:
圖3
圖4
圖5
通過上面的實(shí)際測(cè)試,我們得出,在構(gòu)造結(jié)構(gòu)體復(fù)雜數(shù)據(jù)類型的時(shí)候,成員變量的排放一定要注意順序,遵守排放原則,否則就會(huì)白白浪費(fèi)你的空間,掌握好排放原理,能大大提高你的空間利用率。比如我們構(gòu)造如圖5的結(jié)構(gòu)體類型,它依然還是占8個(gè)字節(jié)。
文末再給大家出個(gè)問題,大家看看下面我們構(gòu)造的數(shù)據(jù)類型,它們分別占的空間是多大呢?
?圖6