1. 程式人生 > >結構體(struct)和聯合體(union)的區別

結構體(struct)和聯合體(union)的區別

兩者最大的區別在於記憶體利用

一、結構體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