اتحاد يمكن تعريفه على أنه نوع بيانات محدد من قبل المستخدم وهو عبارة عن مجموعة من المتغيرات المختلفة لأنواع البيانات المختلفة في نفس موقع الذاكرة. يمكن أيضًا تعريف الاتحاد على أنه العديد من الأعضاء، ولكن يمكن لعضو واحد فقط أن يحتوي على قيمة في وقت معين.
Union هو نوع بيانات محدد من قبل المستخدم، ولكن على عكس الهياكل، فإنهما يشتركان في نفس موقع الذاكرة.
دعونا نفهم هذا من خلال مثال.
إذا كان بيان آخر في Java
struct abc { int a; char b; }
الكود أعلاه هو البنية المعرفة من قبل المستخدم والتي تتكون من عضوين، أي النوع 'a' كثافة العمليات و'ب' من النوع شخصية . عندما تحققنا من عنواني 'أ' و'ب'، وجدنا أن عنوانيهما مختلفان. ولذلك، نستنتج أن الأعضاء في البنية لا يتشاركون في نفس موقع الذاكرة.
عندما نحدد الاتحاد، وجدنا أن الاتحاد يتم تعريفه بنفس الطريقة التي يتم بها تعريف البنية ولكن الفرق هو أن الكلمة الأساسية Union تستخدم لتحديد نوع بيانات الاتحاد، بينما يتم استخدام الكلمة الأساسية struct لتحديد البنية. يحتوي الاتحاد على أعضاء البيانات، أي 'a' و'b'، وعندما قمنا بالتحقق من عناوين كلا المتغيرين وجدنا أن كلاهما لهما نفس العناوين. وهذا يعني أن أعضاء الاتحاد يتشاركون في نفس موقع الذاكرة.
دعونا نلقي نظرة على التمثيل التصويري لتخصيص الذاكرة.
ويوضح الشكل أدناه التمثيل التصويري للهيكل. يتكون الهيكل من عضوين. أي أن أحدهما من نوع عدد صحيح، والآخر من نوع الحرف. بما أن الكتلة الواحدة تساوي بايت واحد؛ لذلك، سيتم تخصيص المتغير 'a' إلى 4 كتل من الذاكرة بينما سيتم تخصيص المتغير 'b' إلى كتلة واحدة من الذاكرة.
والشكل التالي يوضح التمثيل التصويري لأعضاء النقابة. يتشارك كلا المتغيرين في نفس موقع الذاكرة ولهما نفس العنوان الأولي.
جافا الميراث
في الاتحاد، سيشارك الأعضاء موقع الذاكرة. إذا حاولنا إجراء تغييرات في أي من الأعضاء فسوف ينعكس ذلك على العضو الآخر أيضًا. دعونا نفهم هذا المفهوم من خلال مثال.
union abc { int a; char b; }var; int main() { var.a = 66; printf(' a = %d', var.a); printf(' b = %d', var.b); }
في الكود أعلاه، يتكون الاتحاد من عضوين، أي 'أ' و'ب'. 'var' هو متغير من النوع union abc. في ال رئيسي() في الطريقة، قمنا بتعيين المتغير 66 إلى المتغير 'a'، لذلك سيطبع var.a الرقم 66 على الشاشة. نظرًا لأن كلا من 'a' و'b' يشتركان في موقع الذاكرة، فار.ب سوف تطبع' ب (رمز أسكي 66).
تحديد حجم الاتحاد
يعتمد حجم الاتحاد على حجم أكبر عضو في الاتحاد.
دعونا نفهم من خلال مثال.
union abc{ int a; char b; float c; double d; }; int main() { printf('Size of union abc is %d', sizeof(union abc)); return 0; }
كما نعلم، حجم int هو 4 بايت، وحجم char هو 1 بايت، وحجم float هو 4 بايت، وحجم double هو 8 بايت. وبما أن المتغير المزدوج يحتل أكبر ذاكرة بين المتغيرات الأربعة، فسيتم تخصيص إجمالي 8 بايت في الذاكرة. ولذلك، فإن إخراج البرنامج أعلاه سيكون 8 بايت.
الوصول إلى أعضاء الاتحاد باستخدام المؤشرات
يمكننا الوصول إلى أعضاء الاتحاد من خلال المؤشرات باستخدام عامل السهم (->).
دعونا نفهم من خلال مثال.
#include union abc { int a; char b; }; int main() { union abc *ptr; // pointer variable declaration union abc var; var.a= 90; ptr = &var; printf('The value of a is : %d', ptr->a); return 0; }
في الكود أعلاه، قمنا بإنشاء متغير مؤشر، أي *ptr، الذي يخزن عنوان المتغير var. الآن، يمكن لـ ptr الوصول إلى المتغير 'a' باستخدام عامل التشغيل (->). وبالتالي فإن ناتج الكود أعلاه سيكون 90.
لماذا نحتاج إلى نقابات C؟
خذ بعين الاعتبار مثال واحد لفهم الحاجة إلى اتحادات C. لنفكر في متجر يحتوي على عنصرين:
1nf 2nf 3nf
- كتب
- قمصان
يرغب أصحاب المتاجر في تخزين سجلات العنصرين المذكورين أعلاه مع المعلومات ذات الصلة. على سبيل المثال، تتضمن الكتب العنوان والمؤلف وعدد الصفحات والسعر، وتتضمن القمصان اللون والتصميم والحجم والسعر. خاصية 'السعر' شائعة في كلا العنصرين. يريد صاحب المتجر تخزين الخصائص، فكيف سيقوم بتخزين السجلات.
في البداية، قرروا تخزين السجلات في هيكل كما هو موضح أدناه:
struct store { double price; char *title; char *author; int number_pages; int color; int size; char *design; };
يتكون الهيكل أعلاه من جميع العناصر التي يريد صاحب المتجر تخزينها. الهيكل أعلاه قابل للاستخدام بالكامل ولكن السعر ملكية مشتركة في كل من العناصر وبقية العناصر فردية. تنتمي الخصائص مثل السعر، *العنوان، *المؤلف، ورقم الصفحات إلى الكتب بينما ينتمي اللون والحجم *التصميم إلى Shirt.
دعونا نرى كيف يمكننا الوصول إلى أعضاء الهيكل .
int main() { struct store book; book.title = 'C programming'; book.author = 'Paulo Cohelo'; book.number_pages = 190; book.price = 205; printf('Size is : %ld bytes', sizeof(book)); return 0; }
في الكود أعلاه، قمنا بإنشاء متغير من النوع محل . لقد قمنا بتعيين القيم للمتغيرات، العنوان، المؤلف، عدد الصفحات، السعر ولكن متغير الكتاب لا يمتلك خصائص مثل الحجم واللون والتصميم. وبالتالي، فهو إهدار للذاكرة. سيكون حجم البنية أعلاه 44 بايت.
يمكننا توفير الكثير من المساحة إذا استخدمنا النقابات.
#include struct store { double price; union { struct{ char *title; char *author; int number_pages; } book; struct { int color; int size; char *design; } shirt; }item; }; int main() { struct store s; s.item.book.title = 'C programming'; s.item.book.author = 'John'; s.item.book.number_pages = 189; printf('Size is %ld', sizeof(s)); return 0; }
في الكود أعلاه، قمنا بإنشاء متغير من النوع store. نظرًا لأننا استخدمنا الاتحادات في الكود أعلاه، فسيتم أخذ أكبر ذاكرة يشغلها المتغير في الاعتبار عند تخصيص الذاكرة. إخراج البرنامج أعلاه هو 32 بايت. في حالة الهياكل، حصلنا على 44 بايت، بينما في حالة الاتحادات، الحجم الذي تم الحصول عليه هو 44 بايت. وبالتالي، 44 بايت أكبر من 32 بايت مما يوفر الكثير من مساحة الذاكرة.
صفيف مقابل قائمة الصفيف