漫談c語言結(jié)構(gòu)體
再看看char_long_short這個結(jié)構(gòu)體,char_long_short的地址分布情況如下表:
成員變量 | 成員變量十六進制地址 | 成員變量十進制地址 |
char_long_short.c | 0x0012FF2C | 1244972 |
char_long_short.l | 0x0012FF30 | 1244976 |
char_long_short.s | 0x0012FF34 | 1244980 |
可見,其內(nèi)存分布圖如下,共12bytes:
地址 | 1244972 | 1244973 | 1244974 | 1244975 | 1244976 | 1244977 | 1244978 | 1244979 | 1244980 | 1244981 | 1244982 | 1244983 |
成員 | .c | .l | .s |
首先,1244972能被1整除,所以char_long_short.c放在1244972處沒有問題(其實,就char型成員變量自身來說,其放在任何地址單元處都沒有問題),根據(jù)原則1,在之后的1244973~1244975中都沒有能被4(因為sizeof(long)=4bytes)整除的,1244976能被4整除,所以char_long_short.l應(yīng)該放在1244976處,那么同理,最后一個.s(sizeof(short)=2bytes)是應(yīng)該放在1244980處。
是不是這樣就結(jié)束了?不是,還有原則2。根據(jù)原則2的要求,char_long_short這個結(jié)構(gòu)體所占的空間大小應(yīng)該是其占內(nèi)存空間最大的成員變量的大小的整數(shù)倍。如果我們到此就結(jié)束了,那么char_long_short所占的內(nèi)存空間是1244972~1244981共計10bytes,不符合原則2,所以,必須在最后補齊2個bytes(1244982~1244983)。
至此,一個結(jié)構(gòu)體的內(nèi)存布局完成了。
下面我們按照上述原則,來驗證這樣的分析是不是正確。按上面的分析,地址單元1244973、1244974、1244975以及1244982、1244983都是空的(至少char_long_short未用到,只是“占位”了)。如果我們的分析是正確的,那么,定義這樣一個結(jié)構(gòu)體,其所占內(nèi)存也應(yīng)該是12bytes:
struct//聲明結(jié)構(gòu)體char_long_short_new
{
charc;
charadd1;//補齊空間
charadd2;//補齊空間
charadd3;//補齊空間
longl;
shorts;
charadd4;//補齊空間
charadd5;//補齊空間
}char_long_short_new;
運行結(jié)果如下:
可見,我們的分析是正確的。至于原則3,大家可以自己編程驗證,這里就不再討論了。
所以,無論你是在VC6.0還是KeilC51,還是KeilMDK中,當(dāng)你需要定義一個結(jié)構(gòu)體時,只要你稍微留心結(jié)構(gòu)體成員變量內(nèi)存對齊這一現(xiàn)象,就可以在很大程度上節(jié)約MCU的RAM。這一點不僅僅應(yīng)用于實際編程,在很多大型公司,比如IBM、微軟、百度、華為的筆試和面試中,也是常見的。
本例完整的程序代碼下載:http://www.51hei.com/f/cjgt.rar
評論