在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ C語言聯(lián)合體
C語言printf()和scanf()函數(shù)
C語言strlen()函數(shù)
C語言指針
C語言ftell()函數(shù)
C語言#ifdef指令
C語言程序執(zhí)行流程
C語言歷史
C語言fprintf()和fscanf()函數(shù)
C語言#define指令
C語言#if指令
C語言將數(shù)組傳遞給函數(shù)
C語言指針的指針
C語言rewind()函數(shù)
C語言常量
C語言strcat()函數(shù)
C語言#ifndef指令
C語言continue語句
C語言注釋
C語言#include指令
C語言類型轉(zhuǎn)換
C語言strcpy()函數(shù)
C語言strlwr()函數(shù)
C語言while循環(huán)
C語言字符串
C語言strrev()函數(shù)
C語言gets()和puts()函數(shù)
C語言文件處理
C語言存儲分類
C語言運算符
C語言數(shù)據(jù)類型
C語言strcmp()函數(shù)
C語言VS開發(fā)環(huán)境安裝
C語言轉(zhuǎn)義序列
C語言第一個程序
C語言變量
C語言goto語句
C語言預處理器指令
C語言指針算術(shù)運算
C語言數(shù)學函數(shù)
C語言二維數(shù)組
C語言for循環(huán)
C語言命令行參數(shù)
C語言通過值和引用函數(shù)
C語言fputs()和fgets()函數(shù)
C語言do-while循環(huán)
C語言結(jié)構(gòu)體數(shù)組
C語言循環(huán)
C語言#pragma指令
C語言關(guān)鍵字
C語言#error指令
C語言聯(lián)合體
C語言特點
C語言break語句
C語言遞歸
C語言函數(shù)
C語言結(jié)構(gòu)體
C語言switch語句
C語言結(jié)構(gòu)體嵌套
C語言fputc()和fgetc()函數(shù)
C語言fseek()函數(shù)
C語言字符串函數(shù)
C語言if-else語句
C語言教程
C語言宏
C語言數(shù)組
C語言strupr()函數(shù)
C語言#undef指令

C語言聯(lián)合體

像結(jié)構(gòu)體一樣,聯(lián)合體(Union)在C語言中是一個用戶定義的數(shù)據(jù)類型,用于保存不同類型的元素。

但它并不占所有成員的內(nèi)存總和。它只占最大成員的內(nèi)存,它分享最大成員的內(nèi)存。

聯(lián)合體優(yōu)點

它占用較少的內(nèi)存,因為它只占最大的成員的內(nèi)存量。

聯(lián)合體缺點

它將數(shù)據(jù)存儲在一個成員中。

定義聯(lián)合體

union關(guān)鍵字用于定義聯(lián)合體。下面我們來看看如何在C語言中定義聯(lián)合體的語法 -

union union_name   
{  
    data_type member1;  
    data_type member2;  
    .  
    .  
    data_type memeberN;  
};

我們來看看在C語言中定義員工聯(lián)合體的例子。如下代碼 -

union employee  
{   int id;  
    char name[50];  
    float salary;  
};

注:除了union關(guān)鍵字,其它均與結(jié)構(gòu)體一樣。

聯(lián)合體的例子

我們來看看一個簡單的C語言聯(lián)合示例。創(chuàng)建一個源文件:union-example.c,其代碼實現(xiàn)如下 -

#include <stdio.h>  
#include <string.h>  
union employee
{
    int id;
    char name[150];
}e1;  //declaring e1 variable for union  

int main()
{
    //store first employee information  
    e1.id = 1010;
    strcpy(e1.name, "Maxsu");//copying string into char array  
                                     //printing first employee information  
    printf("employee 1 id : %d, address: %u\n", e1.id, &e1.id);
    printf("employee 1 name : %s, address: %u\n", e1.name, &e1.name);
    e1.id = 1010;
    printf("employee 1 id : %d, address: %u\n", e1.id, &e1.id);
    printf("employee 1 name : %s, address: %u\n", e1.name, &e1.name);
    return 0;
}

執(zhí)行上面示例代碼,得到以下結(jié)果 -

employee 1 id : 1937269069, address: 16819328
employee 1 name : Maxsu, address: 16819328
employee 1 id : 1010, address: 16819328
employee 1 name : ?, address: 16819328

如上輸出結(jié)果中可以看到,id字段的值是一個垃圾值,因為name具有大的內(nèi)存大小。所以只有name才具有實際值。

聯(lián)合體完全就是共用一個內(nèi)存首地址,并且各種變量名都可以同時使用,操作也是共同生效。如此多的訪問內(nèi)存手段,確實好用,不過這些“手段”之間卻沒法互相屏蔽——就好像數(shù)組+下標和指針+偏移一樣。

由于聯(lián)合體中的所有成員是共享一段內(nèi)存的,因此每個成員的存放首地址相對于于聯(lián)合體變量的基地址的偏移量為0,即所有成員的首地址都是一樣的。為了使得所有成員能夠共享一段內(nèi)存,因此該空間必須足夠容納這些成員中最寬的成員。對于這句“對齊方式要適合其中所有的成員”是指其必須符合所有成員的自身對齊方式。

下面舉例說明:

union U
{
    char s[9];
    int n;
    double d;
};

s占9字節(jié),n占4字節(jié),d占8字節(jié),因此其至少需9字節(jié)的空間。然而其實際大小并不是9,用運算符sizeof測試其大小為16.這是因為這里存在字節(jié)對齊的問題,9既不能被4整除,也不能被8整除。因此補充字節(jié)到16,這樣就符合所有成員的自身對齊了。從這里可以看出聯(lián)合體所占的空間不僅取決于最寬成員,還跟所有成員有關(guān)系,即其大小必須滿足兩個條件:1)大小足夠容納最寬的成員;2)大小能被其包含的所有基本數(shù)據(jù)類型的大小所整除。

測試程序,創(chuàng)建一個源文件:union-test.c,其代碼實現(xiàn)如下 -

#include <stdio.h>  
#include <string.h>  

union U1
{
    char s[9];
    int n;
    double d;
}u1;

union U2
{
    char s[5];
    int n;
    double d;
}u2;

int main()
{
    printf("%d\n", sizeof(u1));
    printf("%d\n", sizeof(u2));
    printf("0x%x\n", &u1);
    printf("0x%x\n", &u1.s);
    printf("0x%x\n", &u1.n);
    printf("0x%x\n", &u1.d);
    u1.n = 1;
    printf("%d\n", u1.s[0]);
    printf("%lf\n", u1.d);
    unsigned char *p = (unsigned char *)&u1;
    printf("%d\n", *p);
    printf("%d\n", *(p + 1));
    printf("%d\n", *(p + 2));
    printf("%d\n", *(p + 3));
    printf("%d\n", *(p + 4));
    printf("%d\n", *(p + 5));
    printf("%d\n", *(p + 6));
    printf("%d\n", *(p + 7));
    return 0;
}

執(zhí)行上面測試代碼,得到以下結(jié)果 -

16
8
0xeca5a0
0xeca5a0
0xeca5a0
0xeca5a0
1
0.000000
1
0
0
0
0
0
0
0