簡體   English   中英

訪問c中的聯盟成員

[英]access union member in c

我對c語言中的聯合有疑問

例如:

typedef struct {
    int a;
     float c;
}Type1;


typedef struct {
    int b;
     char d;
}Type2;

union Select {
    Type1 type1;
    Type2 type2;
};


void main() {
    Select* select;
    //can we access type1 first and then access type2 immediately? like this way:
    select->type1.a;
    select->type2.b;

//在訪問type1之后,然后立即訪問type2,我們可以得到type2的值b嗎? //我稍微修改了第一篇文章,因為它在開頭是無意義的。

}

這保證可以通過ISO / IEC 9899:1999(見這里的草案 ),6.5.2.3 5:

為了簡化聯合的使用,我們做了一個特殊的保證:如果一個聯合包含幾個共享一個共同初始序列的結構(見下文),並且如果聯合對象當前包含這些結構中的一個,則允許檢查公共其中任何一個的初始部分都可以看到完整類型的聯合聲明。 如果對應的成員具有一個或多個初始成員的序列的兼容類型(並且對於位字段,具有相同的寬度),則兩個結構共享共同的初始序列。

對,那是正確的。 在您的示例中(忽略未初始化的指針),對於任何給定的Select實例, type1.atype2.b的值將始終相同。

在您的示例中,它將起作用,因為兩者都是int類型

通常你需要一個鑒別器來知道一次使用哪個聯合。

聯合具有最大數據類型的大小(如果我記得核心),並且每次設置/檢查類型以了解要訪問的數據類型:

struct myStruct {   
    int type;   
    union Select {   
      Type1 type1;   
      Type2 type2;   
     };  
};  

您將在訪問之前進行檢查以了解如何使用聯合:

myStruct* aStruct;  
//init pointer
    if(aStruct->type == TYPE1)//TYPE1 is defined to indicate the coresponding type
    {
       //access fields of type1
       aStruct->type1.a = //use it
    }

在你應該完成之前: aStruct->type = TYPE1

是的,你可以隨時訪問它們。 基本上select-> type1和select-> type2是指向內存中相同位置的指針。 知道該位置在內存中的位置通常是一個標志:

union Select {
    Type1 type1;
    Type2 type2;
};

struct SelectType {
    bool isType1;
    Select select;
};

int getValue (struct SelectType s){
    if (s.IsType1){
        return s.type1.a;
    } else {
        return s.type2.b;
    }
}

void main() {
    struct SelectType select;
    int value;

    select.type1.a = 5;
    select.isType1 = true;

    select.type2.4 = 5;
    select.isType1 = false;

    value = getValue (select);
}

我們可以。 在這種情況下,它的價值不會改變。 這沒錯,但沒有意義。 順便說一句,你忘了為指針'select'分配內存?

我真的很想幫忙,但我的英語不是很好。 這是我的第一篇文章。 所以,如果我說錯了,請告訴我。

是的,你可以,因為main有你的工會聲明的范圍。

引用C99標准的最終版本。

以下不是有效的片段(因為聯合類型在函數f中不可見)

struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 *p1, struct t2 *p2)
{
    if (p1->m < 0)
        p2->m = -p2->m;
    return p1->m;
}

int g()
{
    union {
        struct t1 s1;
        struct t2 s2;
    } u;
    /* ... */
    return f(&u.s1, &u.s2);
}

聯合中的所有成員都駐留在相同的內存位置。 它通常以不止一種方式訪問​​同一塊內存。

例如,您可以定義:

聯盟{

char a [100];

int b [50];

}X;

union大小為100字節,從b [0]讀取就像讀取[0]和[1]一樣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM