یونیون ها در برنامه نویسی C

در این آموزش با یونیون ها (unions) در برنامه نویسی C آشنا خواهید شد و شیوه ایجاد یونیون ها، دسترسی به اعضای آنها و تفاوت بین یونیون ها و ساختارها را یاد خواهید گرفت.
مفهوم یونیون (Union) یونیونها در زبان برنامهنویسی C نوعی ساختار داده گروهی هستند که به برنامهنویس اجازه میدهند چندین متغیر با نوعهای مختلف را تعریف کند، اما تمام این متغیرها به جای داشتن فضاهای مستقل، یک مکان واحد و مشترک از حافظه سیستم را به اشتراک بگذارند.
ویژگیهای بنیادین
-
اشتراک فضا: تفاوت اصلی یونیون با ساختارهای دیگر این است که سیستمعامل فقط یک بلوک از حافظه را به کل آن اختصاص میدهد و تمام اعضای درون آن به همان یک بلوک اشاره میکنند.
-
محاسبه حجم: اندازه کل یک یونیون در حافظه، دقیقاً برابر با حجم حافظه مورد نیاز برای بزرگترین متغیر درون آن است، نه مجموع حجم تمام متغیرها.
-
دسترسی انحصاری در لحظه: از آنجا که فضای فیزیکی مشترک است، در هر زمان مشخص تنها یکی از متغیرهای درون یونیون میتواند اطلاعات معتبر و سالمی را در خود نگه دارد.
-
بازنویسی خودکار (Overwriting): اگر شما مقداری را به یکی از متغیرهای یونیون اختصاص دهید و بلافاصله مقدار دیگری را در متغیر دوم قرار دهید، اطلاعات قبلی از بین رفته و دادههای جدید مستقیماً روی همان فضای قبلی بازنویسی میشوند.
هدف و فلسفه استفاده کاربرد و هدف اصلی این ساختار، مدیریت و بهینهسازی شدید حافظه است. در محیطهایی که منابع سیستم بهشدت محدود است و برنامهنویس منطقاً میداند که چندین متغیر هرگز قرار نیست به صورت همزمان استفاده شوند، یونیونها با جلوگیری از تخصیص فضاهای مجزا و بلااستفاده، از هدررفت حافظه جلوگیری میکنند.
برای تعریف یونیون ها از کلمه کلیدی union استفاده می شود. مثال،
union car
{
char name[50];
int price;
};
در این کد union car یک نوع مشتق شده است.
نکته: در یونیون ها می توانید چند عضو ایجاد کنید اما در یک زمان مشخص تنها یک عضو می تواند مقدار (درست) داشته باشد.
تعریف متغیرهای union
یونیون یک نوع تعریف شده توسط کاربر است که در هنگام تعریف حافظه ای اختصاص داده نمی شود. برای تخصیص حافظه برای نوع یونیون و کار با آن باید متغیرهایی از نوع یونیون ایجاد کنید.
در کد زیر نحوه تعریف متغیرهای یونیون آورده شده است.
union car
{
char name[50];
int price;
};
int main()
{
union car car1, car2, *car3;
return 0;
}
یک روش دیگر برای تعریف متغیرهای یونیون،
union car
{
char name[50];
int price;
} car1, car2, *car3;
در هر دو مورد، متغیرهای car1، car2 و اشاره گر یونیون car3 از نوع union car ساخته شده اند.
دسترسی به اعضای union
از عملگر . (نقطه) برای دسترسی به اعضای یونیون استفاده می شود. برای دسترسی متغیرهای اشاره گر از عملگر <– استفاده میشود.
در مثال بالا،
- برای دسترسی به price برای متغیرcar1 از car1.price استفاده شده است.
- برای دسترسی به price با car3 از (car3).price* یا car3->price استفاده می شود.
تفاوت بین یونیون ها (union) و ساختارها (structure)
برای نشان دادن تفاوت بین یونیون ها و ساختارها یک مثال می زنیم:
#include
union unionJob
{
// union تعریف
char name[32];
float salary;
int workerNo;
} uJob;
struct structJob
{
char name[32];
float salary;
int workerNo;
} sJob;
int main()
{
printf(“size of union = %d bytes”, sizeof(uJob));
printf(“nsize of structure = %d bytes”, sizeof(sJob));
return 0;
}
خروجی
size of union = 32
size of structure = 40
چرا اندازه متغیرهای یونیون و ساختار متفاوت است؟
در اینجا، اندازه متغیر sJob بابر با ۴۰ بایت است، چون:
- اندازه name[32] برابر با ۳۲ بایت،
- اندازه salary برابر با ۴ بایت،
- و اندازه workerNo برابر با ۴ بایت است.
اندازه uJob برابر با ۳۲ بایت است، زیرا اندازه متغیر union همیشه به اندازه بزرگترین عنصر آن خواهد بود. در مثال بالا، اندازه بزرگترین عنصر (name[32])، ۳۲ بایت است.
در یونیون همه اعضا حافظه مشابهی دارند، در واقع از یک بلوک حافظه استفاده می کنند.
مثال: دسترسی به اعضای Union
#include
union Job {
float salary;
int workerNo;
} j;
int main() {
j.salary = 12.3;
// را نگه دارد ۱۲٫۳ نمی تواند مقدار j.salary ، j.workerNo با مقداردهی
j.workerNo = 100;
printf(“Salary = %.1fn”, j.salary);
printf(“Number of workers = %d”, j.workerNo);
return 0;
}
خروجی
Salary = 0.0
Number of workers = 100
زمانی که j.workerNo مقداردهی می شود، مقدار j.salary نیز تغییر می کند و در همزمان دو عضو نمی توانند مقدار داشته باشند. به دلیل اینکه هر دو متغیر union از یک بلوک مشترک در حافظه استفاده می کنند.
