首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言基礎

C 語言共用體:記憶體覆蓋技術與實戰應用

     編輯:C 語言基礎

共用體與結構體語法相似,但核心機制截然不同:結構體成員各自佔用獨立記憶體,而共用體所有成員共用同一塊記憶體空間,修改任一成員會影響其餘所有成員。

共用體定義與特性

union 共用體名 {
    成員列表
};
  • 共用體大小 = 最大成員的大小。
  • 同一時刻僅能保存一個成員的值,新賦值會覆蓋舊值。
  • 採用記憶體覆蓋技術,節省空間。

建立共用體變數

union data {
    int n;
    char ch;
    double f;
};

// 三種建立變數方式
union data a, b, c;                    // 先定義再宣告
union data { int n; char ch; } a, b, c; // 定義同時宣告
union { int n; char ch; } a, b, c;      // 匿名共用體直接宣告

記憶體分布與成員相互影響演示

#include <stdio.h>
union data {
    int n;
    char ch;
    short m;
};
int main() {
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data)); // 4, 4

    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m); // 40, @, 40

    a.ch = '9';  // ASCII 0x39
    printf("%X, %c, %hX\n", a.n, a.ch, a.m); // 39, 9, 39

    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m); // 2059, Y, 2059

    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m); // 3E25AD54, T, AD54
    return 0;
}

所有成員從記憶體起始位置對齊。修改 ch 影響第 1 位元組,修改 m 影響前 2 位元組,修改 n 影響全部 4 位元組。

大小端模式影響

不同架構(如 x86 小端、部分單片機大端)下,成員在記憶體中的具體分布順序不同,詳細機制請參閱「大端小端」專題。

實戰應用:學生/教師資訊統一表格

學生需記錄分數,教師需記錄授課科目,前四欄相同。利用共用體節省空間:

#include <stdio.h>
#include <stdlib.h>
#define TOTAL 4

struct {
    char name[20];
    int num;
    char sex;
    char profession; // 's' 學生, 't' 教師
    union {
        float score;
        char course[20];
    } sc;
} bodys[TOTAL];

int main() {
    int i;
    for (i = 0; i < TOTAL; i++) {
        printf("Input info: ");
        scanf("%s %d %c %c", bodys[i].name, &bodys[i].num, &bodys[i].sex, &bodys[i].profession);
        if (bodys[i].profession == 's')
            scanf("%f", &bodys[i].sc.score);
        else
            scanf("%s", bodys[i].sc.course);
        fflush(stdin);
    }

    printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
    for (i = 0; i < TOTAL; i++) {
        if (bodys[i].profession == 's')
            printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);
        else
            printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);
    }
    return 0;
}

共用體在嵌入式系統、通訊協定解析、型別轉換等場景極為實用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved