列舉(enum)所佔空間
列舉(enum)
列舉的定義:
enum LOG_LEVEL
{
DBG,
INF,
WAR,
ERR,
FAT,
ALL,
OFF
};
void WriteInfor(LOG_LEVEL level)
{
switch(level)
{
case DBG:
printf("%d\n",DBG);
......
}
}
上述定義的列舉型別,預設為DBG=0,INF=1,依次類推。
(1)列舉型別是實數型別,可以跟int型別相互轉換。 其所定義的常量子與列舉型別有同樣的可見性,即DBG等可以被列舉型別外面的程式碼所看到。列舉型別沒有名字限定作用。struct有名字限定作用。
(2)列舉型別所佔的空間
C++標準文件中是這樣說明的:“列舉型別的尺寸是以能夠容納最大列舉子的值的整數的尺寸”,同時標準中也說名了:“列舉型別中的列舉子的值必須要能夠用一個int型別表述”,也就是說,列舉型別的尺寸不能夠超過int型別的尺寸,但是是不是必須和int型別具有相同的尺寸呢?上面的標準已經說得很清楚了,只要能夠容納最大的列舉子的值的整數就可以了。在VS2010中sizeof的值為4。
(3)列舉和int是否可以互換
列舉長度可能比int小,有些情況下最好不用互換。
enum EType { e1 = 0, e2, e3 }; EType val; std::scanf( "%d", &val );
列舉型別變數的尺寸不一定和int型別相同,這樣一來我們採用%d就 是說將列舉型別變數val當作4位元組的int變數來看待並進行引數壓棧,而在某些編 譯器下sizeof( val )等於1位元組,這樣scanf函式就會將val變數地址中的後續的三 位元組地址也壓入棧中,並對其進行賦值,也許val變數後續的三個位元組的地址沒有 特殊含義可以被改寫(比如是位元組對齊的空地址空間),可能會認為他不會出現錯 誤,其實不然,在scanf函式呼叫結束後會進行棧清理,這樣一來會導致scanf函式 清理了過多的地址空間,從而破壞了外圍函式的棧指標的指向,從而必然會導致程 序執行時錯誤。