Ⅰ 大神看一下這個struct的大小,為什麼
struct aaa{
char a;
short b;
int c;
char d;
short e;
char f;
}cc;
先介紹一個相關的概念——偏移量。偏移量指的是結構體變數中成員的地址和結構體變數地址的差。結構體大小等於最後一個成員的偏移量加上最後一個成員的大小。顯然,結構體變數中第一個成員的地址就是結構體變數的首地址。
實際上,由於存儲變數時地址對齊的要求,編譯器在編譯程序時會遵循兩條原則:一、結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍) 二、結構體大小必須是所有成員大小的整數倍。
第一個成員a的偏移量為0。第二個成員b的偏移量是第一個成員的偏移量加上第一個成員的大小(0+1),其值為1;並不是自身(short)大小的整數倍,因此補上1個空位元組。
第三個成員c的偏移量是(2+2),是自身(int)大小的整數倍,第四個成員d的偏移量為(4+4),是自身(char)大小的整數倍,第五個成員e的偏移量為(8+1),並不是自身(short)大小的整數倍,因此補上1個空位元組。第五個成員f的偏移量為(10+2),是自身(char)大小的整數倍。所以最後大小為13,但是13不是成員中最大int的整數倍,系統需要增加到16。因此最終是16
Ⅱ C++中結構體的大小
結構體(struct)的sizeof值,並不是簡單的將其中各元素所佔位元組相加,而是要考慮到存儲空間的位元組對齊問題。先看下面定義的兩個結構體.
struct
{
char a;
short b;
char c;
}S1;
struct
{
char a;
char b;
short c;
}S2;
分別用程序測試得出sizeof(S1)=6 , sizeof(S2)=4
可見,雖然兩個結構體所含的元素相同,但因為其中存放的元素類型順序不一樣,所佔位元組也出現差異。這就是位元組對齊原因。通過位元組對齊,有助於加快計算機的取數速度,否則就得多花指令周期。
位元組對齊原則
結構體默認的位元組對齊一般滿足三個准則:
1) 結構體變數的首地址能夠被其最寬基本類型成員的大小所整除;
2) 結構體每個成員相對於結構體首地址的偏移量(offset,即每個成員的起始地址)都是成員自身大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充位元組(trailing padding)。
注意:當結構體成員裡面有數組成員時,如int a[10],要看成10個整形變數才參與計算。
通過這三個原則,就不難理解上面兩個struct的差異了.
對於struct S1, 為了使short變數滿足位元組對其准則(2), 即其存儲位置相對於結構體首地址的offset是自身大小(short佔2個位元組)的整數倍,必須在位元組a後面填充一個位元組以對齊;再由准則(3),為了 滿足結構體總大小為short大小的整數倍,必須再在c後面填充一個位元組。
對於struct S2, 卻不必如上所述的填充位元組,因為其直接順序存儲已經滿足了對齊准則。
如果將上面兩個結構體中的short都改為int(佔4個位元組), 那麼會怎麼樣呢? 程序得出sizeof(S1)=12, sizeof(S2)=8
利用上面的准則,也不難計算得出這樣的結果。S1中在a後面填充3個位元組、在c後面填充3個位元組,這樣一共12個位元組;S2中在a、b順序存儲之後填充兩個位元組用以對其,這樣一共就8個位元組。
當然,在某些時候也可以設置位元組對齊方式。這就需要使用 #pragma pack 。
#pragma pack(push) //壓棧保存
#pragma pack(1)// 設置1位元組對齊
struct
{
char a;
short b;
char c;
}S1;
#pragma pack(pop) // 恢復先前設置
如上所示,將對其方式設為1位元組對齊,那麼S1就不填充位元組,sizeof為各元素所佔位元組之和即4。這一點在從外部2進制文件中讀入struct大小的數據到struct中,是很有用的.
另外,還有如下的一種方式:
· __attribute((aligned (n))),讓所作用的結構成員對齊在n位元組自然邊界上。如果結構中有成員的長度大於n,則按照最大成員的長度來對齊。
· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際佔用位元組數進行對齊。
Ⅲ c語言 struct A{int a,b:A*C:}:大小為多少
12個位元組,注意struct結構在計算所佔位元組大小的時候有一個對其的問題,與體系結構和struct內占最大位元組數的變數有關。
Ⅳ 有關struct的大小
這個牽扯到內存對界(memory alignment,又稱為變數對齊 )的問題,方便計算機進行處理,計算機在處理正好機器字長長度的內存單元的時候能發揮較大效率,例如32位及其,處理一個字元,實際上的過程是讀入寄存器一個機器字長的內存數據,然後只處理指定字元的位元組。
s {char c;int i;}; 在sizeof(char)=1 sizeof(int)=4的情況下sizeof(struct s)為什麼經常是8不是5?
這個就是對齊(alignment)的緣故。
那麼什麼是對齊?現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變數的訪問可以從任何地址開始,但實際情況是在訪問特定變數的時候經常在特定的內存地址訪問,這就是對齊。為什麼呢?msdn for vc6中有這么一段:
This principle is especially important when you write code for porting to multiple processors. A misaligned 4-byte data member, which is on an address that is not a multiple of four, causes a performance penalty with an 80386 processor and a hardware exception with a MIPS® RISC processor. In the latter case, although the system handles the exception, the performance penalty is significantly greater.
大意是:1.某些硬體平台只能在某些地址處取某些特定類型的數據,否則拋出硬體異常。2.其餘的硬體平台雖然可以在任何地址處取得任何類型的數據,但如果變數沒有對齊的情況下,取這個數據可能有效率上的損失。
所以為了不出錯或者優化,在訪問特定變數的時候要在特定的內存地址訪問,這也是很多時候管對齊叫優化對齊的緣故。普通情況下編譯器負責做這件事情。對齊問題在移植的時候尤其需要考慮進去。
內存對界主要是方便計算機,一般編譯器都有默認的對界大小(例如機器字長),這個對界大小可調,#pragma pack(對界大小)
struct ab{
char i;
char j;
int p;
}
vc6中int是32比特的數據char仍然8比特,前面兩個char連續存放不超過一個int的大小,新的int p數據從新的適合位置(4的倍數的地址)存放一共4×2=8
struct ab{
char i;
int p;
char j;
}
因為順序不同,int p在中間,兩個char每個都要佔用4位元組,4×3=12
Ⅳ c語言問題,struct的大小
首先int的大小就和編譯器有關.vc的話就是4
另外計算結構體大小的是以結構體中
**所佔位元組最大的變數的倍數**(或者說來對齊的)
簡單點說,結構體大小就是其中變數所佔大小的最小公倍數(這個數還必須大於所有變數所佔大小的和)
你提問中c-1 i-4 f-4 d-8(我用vc)
公倍數是8,16,24,32...所有變數所佔大小和是1+4+4+8=17
所以就是24了.
Ⅵ 結構體struct和聯合體union(聯合)有什麼區別呢
一、結構體struct
各成員各自擁有自己的內存,各自使用互不幹涉,同時存在的,遵循內存對齊原則。一個struct變數的總長度等於所有成員的長度之和。
二、聯合體union
各成員共用一塊內存空間,並且同時只有一個成員可以得到這塊內存的使用權(對該內存的讀寫),各變數共用一個內存首地址。因而,聯合體比結構體更節約內存。一個union變數的總長度至少能容納最大的成員變數,而且要滿足是所有成員變數類型大小的整數倍。不允許對聯合體變數名U2直接賦值或其他操作。
代碼1:對比struct和union佔用內存大小
[code]
#include<stdio.h>
//結構體
struct u //u表示結構體類型名
{
char a; //a表示結構體成員名
int b;
short c;
}U1;
//U1表示結構體變數名
//訪問該結構體內部成員時可以採用U1.a=1;其中"點"表示結構體成員運算符
//聯合體
union u1 //u1表示聯合體類型名
{
char a; //a表示聯合體成員名
int b;
short c;
}U2;
//U2表示聯合體變數名
//訪問該聯合體內部成員時可以採用U2.a=1;其中"點"表示聯合體成員運算符
//主函數
int main(){
printf("%d\n",sizeof(U1));
printf("%d\n",sizeof(U2));
return 0;
}
/*程序運行結果是:
12
4*/
[/code]
所有成員共用一塊存儲空間,在操作不同的成員時,編譯器根據不同的成員類型,按照不同的方式取值。
#include<stdio.h>
//聯合體
union u1
{
char a;
int b;
short c;
}U2;
//主函數
int main(){
U2.a='a';
printf("%c%c\n",U2.b,U2.c);//輸出aa
U2.a='b';
printf("%c%c\n",U2.b,U2.c);//輸出bb
U2.b=0x4241;
printf("%c%c\n",U2.a,U2.c);//輸出AA
return 0;
}
代碼3:union大小計算
union大小計算準則:1、至少要容納最大的成員變數 2、必須是所有成員變數類型大小的整數倍
代碼中U3至少容納最大e[5]=20位元組,同時變數類型最大值是整數倍,即使double(位元組數是8)的整數倍,因而sizeof(U3)=24。
#include<stdio.h>
//聯合體
union u2
{
char a;
int b;
short c;
double d;
int e[5];
}U3;
//主函數
int main(){
printf("%d\n",sizeof(U3));//輸出24
return 0;
}
代碼4:union大小端模式
#include<stdio.h>
//聯合體
union u3
{
char c[4];
int i;
}U4;
//主函數
int main(){
U4.C[0]=0X04;
U4.C[1]=0X03;
U4.C[2]=0X02;
U4.C[3]=0X11;
printf("%x\n",U4.i);//輸出為11020304 小端
return 0;
}
代碼5:struct位元組對齊
U5中a四個位元組,後面b和c加起來3個位元組,正好補1個位元組對齊;U6中b1個位元組,要和後面的a對齊,需要補3個位元組對齊,c也要補1個位元組對齊,因而最終U6為12個位元組。另外,要想改變這種默認對齊設置,可以用
#pragma pack (2) /*指定按2位元組對齊*/
#pragma pack () /*取消指定對齊,恢復預設對齊*/
#include<stdio.h>
//聯合體
struct u4
{
int a;
char b;
short c;
}U5;
struct u5
{
char b;
int a;
short c;
}U6;
//主函數
int main(){
printf("%d\n",sizeof(U5));
printf("%d\n",sizeof(U6));
return 0;
}
//輸出為
//8
//12
Ⅶ C語言中給怎麼給struct定義一個大小
那是當然的,因為其最大容量不能超過一個int量的空間也就是32768,1200的時候,這個結構容量為:1200*30+4=36004.超過了。MAX最大容量只能為1092.
Ⅷ C語言--結構體大小
這與編譯器的編譯選項有關,如果按C語言的本意則結果應為401,但很多編譯器都對結構類型的成員變數進行了按4位元組或8位元組對齊,這樣做可以提高數據存儲速度,對齊後結構的大小就只能是4或8的整數倍。
Ⅸ c語言struct佔用空間大小問題
咋windows下double佔8個位元組,如果考慮對齊那就是ctm和open共用八個位元組,high和low共用八個位元組,close自己用八個位元組,vol自己用八個位元組,所以是32
linux下是double4個位元組吧。
Ⅹ 這個結構體的大小是多少位元組
12個位元組:其中
struct
header
{
BYTE
by;
//1位元組
DWORD
dw;
//4位元組
int
flag;
//4位元組
};
但是,結構體有一種「補齊」,就是按照
整數
型位元組補齊,9位元組補齊到sizeof(int)的
倍數
,就是12了。