ความแตกต่างระหว่างโครงสร้างและสหภาพ


411

มีตัวอย่างที่ดีที่จะให้ความแตกต่างระหว่าง a structและ a unionหรือไม่? โดยทั่วไปฉันรู้ว่าstructใช้หน่วยความจำทั้งหมดของสมาชิกและunionใช้พื้นที่หน่วยความจำสมาชิกที่ใหญ่ที่สุด มีระดับความแตกต่างของระบบปฏิบัติการอื่น ๆ บ้างไหม?

คำตอบ:


677

ด้วยการรวมกันคุณควรใช้องค์ประกอบอย่างใดอย่างหนึ่งเท่านั้นเนื่องจากพวกมันถูกเก็บไว้ที่จุดเดียวกัน สิ่งนี้ทำให้มีประโยชน์เมื่อคุณต้องการเก็บบางสิ่งที่อาจเป็นหนึ่งในหลาย ๆ ประเภท ในทางกลับกัน Struct มีตำแหน่งหน่วยความจำแยกต่างหากสำหรับแต่ละองค์ประกอบและสามารถใช้งานได้ทันที

เพื่อให้ตัวอย่างที่เป็นรูปธรรมเกี่ยวกับการใช้งานของพวกเขาฉันกำลังทำงานกับล่าม Scheme เมื่อไม่นานมานี้และฉันได้วางซ้อนชนิดข้อมูล Scheme ลงในประเภทข้อมูล C เรื่องนี้เกี่ยวข้องกับการจัดเก็บในโครงสร้าง enum ระบุประเภทของค่าและสหภาพในการจัดเก็บค่าที่

union foo {
  int a;   // can't use both a and b at once
  char b;
} foo;

struct bar {
  int a;   // can use both a and b simultaneously
  char b;
} bar;

union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!

struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK

แก้ไข:หากคุณสงสัยว่าการตั้งค่า xb เป็น 'c' จะเปลี่ยนค่าของ xa เป็นอย่างไรโดยทางเทคนิคแล้วการพูดนั้นไม่ได้กำหนดไว้ บนเครื่องจักรที่ทันสมัยที่สุดถ่านคือ 1 ไบต์และ int คือ 4 ไบต์ดังนั้นการให้ xb ค่า 'c' ยังให้ไบต์แรกของ xa ที่ค่าเดียวกัน:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

พิมพ์

99, 99

ทำไมค่าทั้งสองจึงเหมือนกัน? เนื่องจาก 3 ไบต์สุดท้ายของ int 3 เป็นศูนย์ทั้งหมดดังนั้นจึงอ่านได้เป็น 99 ถ้าเราใส่ xa จำนวนมากคุณจะเห็นว่านี่ไม่ใช่กรณีเสมอไป:

union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

พิมพ์

387427, 99

หากต้องการดูค่าหน่วยความจำจริงอย่างใกล้ชิดลองตั้งค่าและพิมพ์ค่าเป็น hex:

union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);

พิมพ์

deadbe22, 22

คุณสามารถเห็นได้อย่างชัดเจนว่าที่ไหน 0x22 เขียนทับ 0xEF

แต่

ใน C ลำดับของไบต์ใน int ไม่ได้ถูกกำหนดไว้ โปรแกรมนี้เขียนทับ 0xEF ด้วย 0x22 บน Mac ของฉัน แต่มีแพลตฟอร์มอื่น ๆ ที่มันจะเขียนทับ 0xDE แทนเพราะลำดับของไบต์ที่ประกอบขึ้นเป็น int ถูกสลับกลับ ดังนั้นเมื่อเขียนโปรแกรมคุณไม่ควรพึ่งพาพฤติกรรมของการเขียนทับข้อมูลเฉพาะในสหภาพเพราะมันไม่สามารถพกพาได้

สำหรับการอ่านเพิ่มเติมเกี่ยวกับการสั่งซื้อของไบต์ตรวจสอบendianness


1
ใช้ตัวอย่างนี้ในสหภาพถ้า xb = 'c' สิ่งที่ได้รับการจัดเก็บใน xa? มันคือหมายเลขอ้างอิงของถ่านหรือไม่
kylex

1
หวังว่าจะอธิบายรายละเอียดเพิ่มเติมสิ่งที่เก็บไว้ใน xa เมื่อคุณตั้ง xb
Kyle Cronin

1
@ KyleCronin ฉันคิดว่าฉันได้รับมัน ในกรณีของคุณคุณมีกลุ่มของประเภทรู้ว่าคุณจะต้องใช้อย่างใดอย่างหนึ่งเท่านั้น แต่คุณไม่รู้ว่าจะใช้อันไหนจนกว่าจะถึงรันไทม์ - ดังนั้นสหภาพจึงอนุญาตให้คุณทำเช่นนั้นได้ ขอบคุณ
user12345613

2
@ user12345613 สหภาพสามารถใช้เป็นประเภทพื้นฐานสำหรับการจัดโครงสร้าง คุณสามารถเลียนแบบลำดับชั้น OO โดยใช้ยูเนี่ยนของ structs
มอร์เทนเจนเซ่น

1
@Lazar Byte order ในแบบหลายไบต์ขึ้นอยู่กับ endianness ฉันขอแนะนำให้อ่านบทความ Wikipedia เกี่ยวกับเรื่องนี้
Kyle Cronin

83

นี่คือคำตอบสั้น ๆ : โครงสร้างเป็นโครงสร้างบันทึก: องค์ประกอบในโครงสร้างแต่ละจัดสรรพื้นที่ใหม่ ดังนั้นโครงสร้างเช่น

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

จัดสรร(sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))หน่วยความจำอย่างน้อยไบต์สำหรับแต่ละอินสแตนซ์ ("อย่างน้อย" เพราะข้อ จำกัด การวางแนวสถาปัตยกรรมอาจบังคับให้คอมไพเลอร์บีบอัด struct)

ในทางกลับกัน,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

จัดสรรหนึ่งหน่วยความจำและให้สี่นามแฝง ดังนั้นsizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double))อีกครั้งด้วยความเป็นไปได้ของการเพิ่มบางอย่างสำหรับการจัดตำแหน่ง


53

มีตัวอย่างที่ดีที่จะให้ความแตกต่างระหว่าง 'struct' และ 'สหภาพ' หรือไม่?

โปรโตคอลการสื่อสารในจินตนาการ

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

ในโปรโตคอลจินตภาพนี้มีการแยกว่าตาม "ประเภทข้อความ" ตำแหน่งต่อไปนี้ในส่วนหัวจะเป็นหมายเลขคำขอหรือรหัสตัวอักษรสี่ตัว แต่ไม่ใช่ทั้งสองอย่าง กล่าวโดยสรุปคือสหภาพอนุญาตให้ที่เก็บข้อมูลเดียวกันแสดงประเภทข้อมูลได้มากกว่าหนึ่งประเภทโดยมีการรับประกันว่าคุณจะต้องการจัดเก็บข้อมูลประเภทใดประเภทหนึ่งในแต่ละครั้ง

สหภาพแรงงานส่วนใหญ่เป็นรายละเอียดในระดับต่ำซึ่งมีพื้นฐานมาจากมรดกของ C ในฐานะภาษาการเขียนโปรแกรมระบบซึ่งบางครั้งมีการใช้สถานที่เก็บข้อมูล "ที่ทับซ้อนกัน" ด้วยวิธีนี้ บางครั้งคุณสามารถใช้สหภาพเพื่อบันทึกหน่วยความจำที่คุณมีโครงสร้างข้อมูลที่จะบันทึกเพียงหนึ่งประเภทเท่านั้นในคราวเดียว

โดยทั่วไปแล้วระบบปฏิบัติการไม่สนใจหรือรู้เกี่ยวกับ structs และสหภาพ - ทั้งคู่เป็นเพียงหน่วยความจำของมัน struct คือบล็อกของหน่วยความจำที่เก็บวัตถุข้อมูลหลายอย่างโดยที่วัตถุเหล่านั้นไม่ทับซ้อนกัน การรวมกันเป็นบล็อกของหน่วยความจำที่เก็บวัตถุข้อมูลหลายอย่าง แต่มีที่เก็บข้อมูลสำหรับวัตถุที่มีขนาดใหญ่ที่สุดเท่านั้นและสามารถเก็บวัตถุข้อมูลได้เพียงครั้งเดียวในแต่ละครั้ง


1
อ๋อ นี่อธิบายถึงกรณีใช้งานอย่างดี!
gideon

1
สมมติว่าคุณมีpacketheader ph;การเข้าถึงขอหมายเลข? ph.request.requestnumber?
justin.m.chase

คำอธิบายที่ดีที่สุด! ขอบคุณ
84RR1573R

39

ในขณะที่คุณพูดถึงคำถามของคุณความแตกต่างที่สำคัญระหว่างunionและstructคือunionสมาชิกซ้อนทับความทรงจำของกันและกันเพื่อให้ขนาดของสหภาพเป็นหนึ่งในขณะที่structสมาชิกวางกันหลังจากนั้น สหภาพมีขนาดใหญ่พอที่จะมีสมาชิกทั้งหมดและมีการจัดตำแหน่งที่เหมาะกับสมาชิกทั้งหมด สมมุติว่าintสามารถเก็บได้ที่ 2 ไบต์เท่านั้นและกว้าง 2 ไบต์และยาวสามารถเก็บได้ที่ 4 ไบต์เท่านั้นและยาว 4 ไบต์ สหภาพดังต่อไปนี้

union test {
    int a;
    long b;
}; 

อาจมีค่าsizeof4 และข้อกำหนดการจัดตำแหน่งของ 4 ทั้งสหภาพและโครงสร้างสามารถมีช่องว่างภายในท้ายที่สุด แต่ไม่ใช่จุดเริ่มต้น การเขียนไปที่ struct จะเปลี่ยนเฉพาะค่าของสมาชิกที่เขียนไป การเขียนถึงสมาชิกของสหภาพจะทำให้มูลค่าของสมาชิกอื่น ๆ ทั้งหมดไม่ถูกต้อง คุณไม่สามารถเข้าถึงพวกเขาหากคุณไม่ได้เขียนถึงพวกเขามาก่อนมิฉะนั้นพฤติกรรมจะไม่ได้กำหนด GCC เป็นส่วนเสริมที่คุณสามารถอ่านได้จริงจากสมาชิกของสหภาพแม้ว่าคุณจะไม่ได้เขียนถึงพวกเขาล่าสุด สำหรับระบบปฏิบัติการนั้นไม่จำเป็นต้องกังวลว่าโปรแกรมผู้ใช้จะเขียนไปยังสหภาพหรือโครงสร้าง นี่เป็นเพียงปัญหาของคอมไพเลอร์

อีกคุณสมบัติที่สำคัญของสหภาพและ struct คือพวกเขาอนุญาตให้ตัวชี้ไปยังพวกเขาสามารถชี้ไปที่ประเภทใด ๆ ของสมาชิก ดังนั้นสิ่งต่อไปนี้ที่ถูกต้อง:

struct test {
    int a;
    double b;
} * some_test_pointer;

some_test_pointer สามารถชี้ไปหรือint* double*ถ้าคุณโยนอยู่ของประเภทtestการint*ก็จะชี้ไปยังสมาชิกคนแรกของตนaจริง เช่นเดียวกันสำหรับสหภาพด้วย ดังนั้นเนื่องจากสหภาพจะมีการจัดตำแหน่งที่ถูกต้องเสมอคุณสามารถใช้สหภาพเพื่อให้การชี้ไปที่ประเภทที่ถูกต้อง:

union a {
    int a;
    double b;
};

การรวมกันนั้นจะสามารถชี้ไปที่ int และ double:

union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;    

ถูกต้องจริงตามที่ระบุไว้โดยมาตรฐาน C99:

วัตถุต้องมีค่าที่เก็บไว้เข้าถึงได้โดยนิพจน์ lvalue ที่มีประเภทใดประเภทหนึ่งต่อไปนี้:

  • ชนิดที่เข้ากันได้กับชนิดของวัตถุที่มีประสิทธิภาพ
  • ...
  • ประเภทรวมหรือสหภาพที่มีหนึ่งในประเภทดังกล่าวในหมู่สมาชิก

คอมไพเลอร์จะไม่เพิ่มประสิทธิภาพออกv->a = 10;เป็นมันอาจส่งผลกระทบต่อมูลค่าของ*some_int_pointer(และฟังก์ชั่นจะกลับมา10แทน5)


18

A unionมีประโยชน์ในบางสถานการณ์ unionสามารถเป็นเครื่องมือสำหรับการจัดการในระดับต่ำมากเช่นการเขียนโปรแกรมควบคุมอุปกรณ์สำหรับเคอร์เนล

ตัวอย่างของการที่มีการผ่าfloatจำนวนโดยใช้unionของstructที่มี bitfields floatและ ฉันบันทึกหมายเลขไว้ในfloatและหลังจากนั้นฉันสามารถเข้าถึงบางส่วนของที่floatผ่านstructได้ ตัวอย่างแสดงวิธีการunionใช้มุมมองต่างๆในการดูข้อมูล

#include <stdio.h>                                                                                                                                       

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

ลองดูที่คำอธิบายความแม่นยำเดียวในวิกิพีเดีย ฉันใช้ตัวอย่างและหมายเลขเวทย์มนตร์ 0.15625 จากที่นั่น


unionนอกจากนี้ยังสามารถใช้ในการดำเนินการประเภทข้อมูลเกี่ยวกับพีชคณิตที่มีหลายทางเลือก ฉันพบตัวอย่างของสิ่งนั้นในหนังสือ "Real World Haskell" โดย O'Sullivan, Stewart และ Goerzen ตรวจสอบในส่วนสหภาพแยกปฏิบัติ

ไชโย!


11

" union " และ " struct " เป็นโครงสร้างของภาษา C การพูดถึงความแตกต่างระหว่าง "ระดับระบบปฏิบัติการ" นั้นไม่เหมาะสมเนื่องจากเป็นคอมไพเลอร์ที่สร้างรหัสที่แตกต่างกันหากคุณใช้คำหลักหนึ่งคำหรือคำอื่น


11

เทคนิคการพูดที่ไม่ได้หมายถึง:

อัสสัมชัญ: chair = บล็อกหน่วยความจำ, คน = ตัวแปร

โครงสร้าง : ถ้ามี 3 คนพวกเขาสามารถนั่งในเก้าอี้ขนาดเดียวกัน

ยูเนี่ยน : ถ้ามี 3 คนมีเก้าอี้เดียวเท่านั้นที่จะนั่งทุกคนต้องใช้เก้าอี้ตัวเดิมเมื่อพวกเขาต้องการนั่ง

เทคนิคการพูดหมายถึง:

โปรแกรมที่กล่าวถึงด้านล่างให้การดำน้ำลึกเข้าไปในโครงสร้างและการรวมกัน

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

Total MAIN_STRUCT size = sizeof (UINT64) สำหรับ bufferaddr + sizeof (UNIT32) สำหรับ union + 32 บิตสำหรับการขยาย (ขึ้นอยู่กับสถาปัตยกรรมหน่วยประมวลผล) = 128 บิต สำหรับโครงสร้างสมาชิกทั้งหมดจะได้รับบล็อกหน่วยความจำต่อเนื่อง

ยูเนี่ยนได้หนึ่งบล็อกหน่วยความจำของสมาชิกขนาดสูงสุด (นี่คือ 32 บิต) ภายในการรวมโครงสร้างอีกหนึ่งการโกหก (INNER_STRUCT) สมาชิกจะได้รับบล็อกหน่วยความจำขนาดรวม 32 บิต (16 + 8 + 8) ในการรวมสมาชิก INNER_STRUCT (32 บิต) หรือข้อมูล (32 บิต) สามารถเข้าถึงได้


คำอธิบายที่ดี ไชโย!
เปรม

11

ใช่ความแตกต่างหลักระหว่าง struct และ union นั้นเหมือนกับที่คุณระบุไว้ โครงสร้างใช้หน่วยความจำทั้งหมดของสมาชิกและสหภาพใช้พื้นที่หน่วยความจำสมาชิกที่ใหญ่ที่สุด

แต่ความแตกต่างทั้งหมดขึ้นอยู่กับการใช้งานที่ต้องการของหน่วยความจำ การใช้งานที่ดีที่สุดของสหภาพสามารถเห็นได้ในกระบวนการของยูนิกซ์ที่เราใช้สัญญาณ เช่นเดียวกับกระบวนการสามารถกระทำได้โดยสัญญาณเดียวเท่านั้นในแต่ละครั้ง ดังนั้นการประกาศทั่วไปจะเป็น:

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

ในกรณีนี้กระบวนการใช้เฉพาะหน่วยความจำสูงสุดของสัญญาณทั้งหมด แต่ถ้าคุณใช้ struct ในกรณีนี้การใช้หน่วยความจำจะเป็นผลรวมของสัญญาณทั้งหมด สร้างความแตกต่างอย่างมาก

ในการสรุปควรเลือก Union หากคุณทราบว่าคุณเข้าถึงสมาชิกคนใดคนหนึ่งในแต่ละครั้ง


10

คุณมีมันคือทั้งหมดที่ แต่โดยทั่วไปแล้วประเด็นของสหภาพคืออะไร

คุณสามารถใส่เนื้อหาตำแหน่งเดียวกันกับประเภทที่แตกต่างกัน คุณต้องรู้ประเภทของสิ่งที่คุณเก็บไว้ในสหภาพ (บ่อยครั้งที่คุณใส่ไว้ในstructด้วยแท็กประเภท ... )

ทำไมสิ่งนี้จึงสำคัญ ไม่ใช่เพื่อกำไรจากอวกาศ ใช่คุณสามารถรับบิตหรือแพ็ดดิ้งได้ แต่นั่นไม่ใช่ประเด็นหลักอีกต่อไป

เพื่อความปลอดภัยประเภทนี้ช่วยให้คุณสามารถ 'พิมพ์แบบไดนามิก' บางชนิด: คอมไพเลอร์รู้ว่าเนื้อหาของคุณอาจมีความหมายแตกต่างกันและความหมายที่แม่นยำของการตีความของคุณขึ้นอยู่กับคุณในเวลาทำงาน หากคุณมีตัวชี้ที่สามารถชี้ไปที่ประเภทที่แตกต่างกันคุณต้องใช้สหภาพมิฉะนั้นรหัสคุณอาจไม่ถูกต้องเนื่องจากปัญหานามแฝง (คอมไพเลอร์บอกกับตัวเองว่า "โอ้ตัวชี้นี้เท่านั้นที่สามารถชี้ไปที่ประเภทนี้ได้ เข้าถึงสิ่งเหล่านั้น ... "และสิ่งเลวร้ายก็เกิดขึ้นได้)


9

โครงสร้างจะจัดสรรขนาดทั้งหมดขององค์ประกอบทั้งหมดในนั้น

สหภาพจะจัดสรรหน่วยความจำให้มากที่สุดเท่าที่สมาชิกต้องการมากที่สุด


2
คุณอาจต้องการเพิ่ม "การซ้อนทับ" ของสมาชิกสหภาพในการเริ่มต้นที่ที่อยู่เริ่มต้นของโครงสร้างการรวมที่จัดสรร
Jim Buck

4

ความแตกต่างระหว่างโครงสร้างและสหภาพคืออะไร?

คำตอบทางลัดคือ: การเคารพนั้นอยู่ในการจัดสรรหน่วยความจำ คำอธิบาย: ในโครงสร้างพื้นที่หน่วยความจำจะถูกสร้างขึ้นสำหรับสมาชิกทั้งหมดภายในโครงสร้าง ในพื้นที่หน่วยความจำร่วมจะถูกสร้างขึ้นสำหรับสมาชิกที่ต้องการพื้นที่หน่วยความจำที่ใหญ่ที่สุดเท่านั้น พิจารณารหัสต่อไปนี้:

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

ที่นี่มีสมาชิกสองคนใน struct และ union: int และ long int พื้นที่หน่วยความจำสำหรับ int คือ: 4 ไบต์และพื้นที่หน่วยความจำสำหรับ int ยาวคือ 8 ในระบบปฏิบัติการ 32 บิต

ดังนั้นสำหรับ struct 4 + 8 = 12 ไบต์จะถูกสร้างขึ้นในขณะที่ 8 ไบต์จะถูกสร้างขึ้นสำหรับการรวมกัน

ตัวอย่างรหัส:

#include<stdio.h>
struct s_tag
{
  int a;
  long int b;
} x;
union u_tag
{
     int a;
     long int b;
} y;
int main()
{
    printf("Memory allocation for structure = %d", sizeof(x));
    printf("\nMemory allocation for union = %d", sizeof(y));
    return 0;
}

Ref: http://www.codingpractise.com/home/c-programming/structure-and-union/


3

การใช้สหภาพถูกใช้บ่อย ๆ เมื่อต้องการการสนทนาประเภทพิเศษ เพื่อให้เข้าใจถึงประโยชน์ของสหภาพ ไลบรารีมาตรฐาน c / c กำหนดว่าไม่มีฟังก์ชั่นที่ออกแบบมาเป็นพิเศษเพื่อเขียนจำนวนเต็มสั้น ๆ ไปยังไฟล์ การใช้ fwrite () จะเกิดค่าใช้จ่ายมากเกินไปสำหรับการใช้งานที่ง่าย อย่างไรก็ตามการใช้สหภาพคุณสามารถสร้างฟังก์ชั่นที่เขียนเลขฐานสองของจำนวนเต็มแบบสั้นไปยังไฟล์ทีละหนึ่งไบต์ ฉันคิดว่าจำนวนเต็มสั้น ๆ นั้นยาว 2 ไบต์

ตัวอย่าง:

#include<stdio.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

แม้ว่า putw () ฉันเรียกด้วยจำนวนเต็มสั้น ๆ มันเป็นไปได้ที่จะใช้ putc () และ fwrite () แต่ฉันต้องการแสดงตัวอย่างเพื่อควบคุมการใช้สหภาพ


3

โครงสร้างคือการรวบรวมประเภทข้อมูลที่แตกต่างกันซึ่งประเภทของข้อมูลที่แตกต่างกันสามารถอยู่ในนั้นและทุกคนได้รับบล็อกหน่วยความจำของตัวเอง

เรามักจะใช้ยูเนี่ยนเมื่อเราแน่ใจว่าจะใช้เพียงหนึ่งตัวแปรในครั้งเดียวและคุณต้องการใช้ประโยชน์เต็มที่จากหน่วยความจำปัจจุบันเพราะมันจะได้รับหน่วยความจำเพียงหนึ่งบล็อกซึ่งเท่ากับประเภทที่ใหญ่ที่สุด

struct emp
{
    char x;//1 byte
    float y; //4 byte
} e;

หน่วยความจำทั้งหมดที่ได้รับ => 5 ไบต์

union emp
{
    char x;//1 byte
    float y; //4 byte
} e;

หน่วยความจำทั้งหมดที่ได้รับ = 4 ไบต์


2

สหภาพมีประโยชน์ในขณะที่เขียนฟังก์ชั่นการสั่งซื้อแบบไบท์ซึ่งได้รับด้านล่าง มันเป็นไปไม่ได้กับ structs

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.

1

ยูเนี่ยนจะแตกต่างจากโครงสร้างที่ยูเนี่ยนซ้ำกว่าคนอื่น ๆ : มันนิยามหน่วยความจำเดียวกันในขณะที่โครงสร้างกำหนดหนึ่งหลังจากที่อื่น ๆ โดยไม่ทับซ้อนกันหรือนิยามใหม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.