由於存在一些無關標誌(sta_scan
,search
),它們在下面的結構中定義爲位域。這些標誌被宣佈的位置是否重要(在內存保存方面)?結構中的位域位置
struct sta_all {
char name[16];
unsigned int sta_scan:1;
...
int interval;
unsigned int search:1;
}
由於存在一些無關標誌(sta_scan
,search
),它們在下面的結構中定義爲位域。這些標誌被宣佈的位置是否重要(在內存保存方面)?結構中的位域位置
struct sta_all {
char name[16];
unsigned int sta_scan:1;
...
int interval;
unsigned int search:1;
}
是,但並非總是如此。
檢查這個例子:
#include <stdio.h>
#include <string.h>
struct {
char name[16];
unsigned int sta_scan:1;
int interval;
unsigned int search:1;
} sta_all;
int main() {
sta_all.interval = 4;
printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all));
return 0;
}
輸出:
的sizeof(sta_all):28
和:
#include <stdio.h>
#include <string.h>
struct {
char name[16];
unsigned int sta_scan:1;
unsigned int search:1;
int interval;
} sta_all;
int main() {
sta_all.interval = 4;
printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all));
return 0;
}
輸出:
的sizeof(sta_all):24
發生這種情況是因爲填充,on my platform。順便說一句,如果你真的非常渴望記憶效率,並且你可以接受速度損失,那麼你可以使用包裝,正如上面的鏈接所解釋的那樣。
注:上面的例子證實了在提到Jonathan Leffler此comment:
那些位字段中的每一個可能被分配儘可能多的空間的基本類型(
unsigned int
)並且將使用32 1 (16,64,...)位。如果你決定使用位域,你應該確保所有的位域聚集在一起;它會盡量減少浪費的空間。 [...]。在結構的上下文中,編譯器沒有自由移動位域。
..這涉及到完美的和諧與鏈接的答案,因爲編譯器將具有添加量少char gap_{i}[3];
,當我們聚集了位域,從而最大限度地減少了STRUC的大小!
它值得嗎?
沒有那麼多恕我直言......:)
爲什麼你把巨大的領域的OP沒有使相對差異似乎人爲地小? –
@R ..只是爲了好玩。但行爲當然不會改變。檢查我的更新,你現在喜歡我的答案嗎? :) – gsamaras
如果是24 vs 28(不添加愚蠢的花車),我會更喜歡它。 –
一般來說,是的。結構元素通常會以某種方式對齊(通常與元素的大小有時會更大),並且混合各種大小會導致大量填充。有辦法來緩解這一點。一般來說,如果將所有相同大小的元素分組在一起,則可能會打包而沒有任何填充。可以使用pragma強制一個結構被壓縮而沒有填充,但是這會導致對結構成員的非法訪問效率低下。
您不能在位域上強制不填充。 –
這些位字段中的每一個都可能被分配與基本類型('unsigned int')相同的空間,並將使用該存儲單元中的32位(16,64,...)位中的一位。如果你決定使用位域,你應該確保所有的位域聚集在一起;它會盡量減少浪費的空間。你應該考慮'bool'(來自''還是'_Bool')是否也可以用於你的目的,或者更好。許多有關位字段的細節都是實現定義的,但在結構的上下文中,編譯器沒有自由移動位字段。 –
編譯器不允許[重新排序struct成員](http://stackoverflow.com/q/9486364/995714),所以你需要自己去做,除非你啓用了一些[編譯器選項](http://stackoverflow.com/q/14671253/995714) –
artM很好的問題,我從昨天晚上開始編輯我的答案,而不是在牀上數羊,我只是在數點數,希望你會發現它有幫助! :) – gsamaras