結構體(struct)和聯合體(union)的區別
阿新 • • 發佈:2019-01-22
兩者最大的區別在於記憶體利用
一、結構體struct
各成員各自擁有自己的記憶體,各自使用互不干涉,同時存在的,遵循記憶體對齊原則。一個struct變數的總長度等於所有成員的長度之和。
二、聯合體union
各成員共用一塊記憶體空間,並且同時只有一個成員可以得到這塊記憶體的使用權(對該記憶體的讀寫),各變數共用一個記憶體首地址。因而,聯合體比結構體更節約記憶體。一個union變數的總長度至少能容納最大的成員變數,而且要滿足是所有成員變數型別大小的整數倍。不允許對聯合體變數名U2直接賦值或其他操作。
程式碼1:對比struct和union佔用記憶體大小
#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*/
程式碼2:union成員賦值
所有成員共用一塊儲存空間,在操作不同的成員時,編譯器根據不同的成員型別,按照不同的方式取值。
#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