آموزش struct، union، enum و typedef در زبان برنامه‌نویسی C - قسمت 20 آموزش امبدد C

MasoudHD
143 بازدید
۱۴۰۴-۰۳-۱۰
6 دقیقه
  • نویسنده: Alireza Abbasi
  • درباره نویسنده: ---

ساخت نوع داده‌ی سفارشی

در این بخش می‌خواهیم سه نوع داده‌ی سفارشی موجود در زبان C یعنی struct، union و enum را با یکدیگر ترکیب کنیم و یک شکل هندسی را روی صفحه نمایش رسم نماییم. این شکل می‌تواند مربع، مستطیل، دایره یا مثلث باشد که هر یک به روش خاصی توصیف می‌شوند.

برای توصیف یک مربع فقط به یک ضلع نیاز داریم:

برای توصیف یک مستطیل به عرض و ارتفاع نیاز داریم:

با داشتن شعاع می‌توانیم یک دایره رسم کنیم:

در نهایت، برای رسم یک مثلث، قاعده و ارتفاع آن را توصیف می‌کنیم:

برای تعریف نوع داده‌ی کلی برای اشکال مختلف، به ساختاری نیاز داریم که باید بتواند هر کدام از این موارد را نگه‌داری کند که نشان می‌دهد به یک union نیاز داریم. اما برای رسم یک‌ شکل، نه‌تنها به توصیف آن، بلکه به نوع شکل (shape) نیز نیاز داریم. نوع داده‌ی enum برای لیست محدودی از مقادیر ساده طراحی شده است:

حالا می‌توانیم ساختار داده‌ی خود را تعریف کنیم:

اولین فیلد، type، حاوی نوع شکلی (shape) است که در ساختار قرار دارد. فیلد دوم ابعاد شکل را در بر می‌گیرد که از union استفاده شده است، زیرا اشکال مختلف دارای ابعاد متفاوتی هستند.

✅ نکته

اندازه‌ی union همیشه برابر بزرگ‌ترین عضو آن است. بنابراین اگر در union عضو 1 بایتی و 4 بایتی وجود داشته باشد، اندازه‌ی union برابر 4 بایت می‌باشد.

 

کد مربوط به رسم شکل‌ها به‌صورت زیر است:

 

این الگوی طراحی در برنامه‌نویسی C رایج است: یک union که می‌تواند انواع مختلفی از داده‌ها را نگه دارد و یک enum که نوع داده‌ی موردنظر را مشخص می‌کند.

ساختارها و برنامه‌نویسی امبدد

در این بخش با توجه به مطالب که تا اینجا آموختیم، مشخصات یک سخت‌افزار را تبدیل به ساختار (structure) در زبان C می‌کنیم.

رابط سیستم کامپیوتری کوچک (Small Computer System Interface)  یا به اختصار SCSI برای ارائه روشی استاندارد جهت انتقال داده بین دستگاه‌ها طراحی شده است. این رابط در سال ۱۹۸۶ راه‌اندازی شد و از آن زمان تاکنون به طور قابل توجهی توسعه یافته و بهبود پیدا کرده است. SCSI با ارسال یک ساختار به نام “بلوک کامند” به دستگاه و دریافت داده و پیام‌های وضعیت در مقابل آن کار می‌کند.

هنگامی که استاندارد SCSI برای اولین‌بار نوشته شد، کامند READ (6) را تعریف کرد که آدرس بلوک را به 16 بیت محدود می‌کرد. این محدودیت به معنای امکان استفاده از دیسکی تا حداکثر 16 مگابایت بود که برای آن زمان حجم بزرگی محسوب می‌شد.

باتوجه‌به نیاز دیسک‌های بزرگ‌تر، متخصصان SCSI مجبور به ایجاد کامند‌های جدیدی برای پشتیبانی از این نوع دیسک‌ها شدند. به ترتیب، دستورات READ (10)، READ (12)، READ (16) و READ (32) ارائه شد.

 کامند READ (32) از یک آدرس بلوک 64 بیتی استفاده می‌کند که امکان استفاده از دیسک‌های بسیار بزرگ‌تر را فراهم می‌کند.

شکل زیر بلوک کامند مربوط به دستور READ (10) را نشان می‌دهد. برای خواندن داده‌ها از دیسک، به یک ساختار C نیاز داریم تا این اطلاعات را در خود جای دهد و آن را به دستگاه ارسال کند.

 

بلوک کامند READ (10)

بلوک کامند READ (10)

در نگاه اول، به نظر ترجمه ساده‌ای می‌آید:

به‌خاطر اینکه ما محتاط و دقیق هستیم، اولین کاری که در برنامه انجام دادیم قراردادن یک دستور assert بود تا اطمینان پیدا کنیم تعریف ما از ساختار read10 با سخت‌افزار مطابقت دارد. دستور assert درصورتی‌که شرط تعریف شده برقرار نباشد، برنامه را متوقف می‌کند. در این مثال، انتظار داشتیم بلوک کنترل read10 دقیقاً ۱۰ بایت حجم داشته باشد، اما خروجی دستور assert نشان داد که این‌طور نیست و مشکلی وجود دارد. ما هم با مشکل مواجه شدیم؛ چون دستور assert با شکست مواجه شد.

اما چرا این اتفاق افتاد؟ با بررسی دقیق‌تر ساختار، متوجه می‌شویم که فیلد lba (از نوع uint32_t) روی یک مرز ۲ بایتی تراز شده است. کامپایلر ترجیح می‌دهد این فیلد را روی یک مرز ۴ بایتی قرار دهد، بنابراین برای اینکه ترازبندی را برقرار کند، ۲ بایت پرکننده (padding) به ساختار اضافه کرده است. برای اینکه ساختار ما دقیقاً ۱۰ بایت حجم داشته باشد و با سخت‌افزار مطابقت پیدا کند، نیاز به فشرده کردن ساختار (packing) داریم:

برای اینکه ساختار ما دقیقاً ۱۰ بایت داشته باشد و با سخت‌افزار مطابقت کند، از ویژگی packed استفاده می‌کنیم. این ویژگی به کامپایلر GCC دستور می‌دهد که هیچ بایت پرکننده‌ای به ساختار اضافه نکند. در نتیجه، ساختار ما از نظر کارایی ممکن است ایده‌آل نباشد، اما به‌این‌ترتیب با سخت‌افزار مطابقت پیدا می‌کند. نکته مهم این است که با استفاده از ویژگی packed دستور assert ما با موفقیت اجرا می‌شود و نشان می‌دهد که حجم ساختار صحیح است.

typedef

کلیدواژه typedef در زبان برنامه‌نویسی C به ما امکان می‌دهد که برای انواع داده موجود، نام‌های جدید تعریف کنیم. برای مثال، دستور زیر یک نوع داده جدید به نام dimension تعریف می‌کند:

این نوع داده معادل unsigned int است و می‌توان از آن مانند هر نوع داده دیگری استفاده کرد:

 عرض شیء بر حسب) furlong واحد اندازه‌گیری قدیمی(   //

نحوه نوشتن typedef شبیه به تعریف یک متغیر است. این دستور شامل کلیدواژه typedef، نام اولیه و همچنین نام جدید تعریف‌شده می‌باشد:

یک مثال از typedef را می‌توان در فایل stdint.h پیدا کرد که در بسیاری از برنامه‌های ما گنجانده شده است:

در اوایل پیدایش زبان C، بسته به پردازنده، نوع داده int می‌توانست ۱۶ یا ۳۲ بیتی باشد. در اوایل برنامه‌نویسی، اگر کاربران می‌خواستند از یک عدد صحیح ۱۶ بیتی (که استاندارد قدیمی C از آن پشتیبانی نمی‌کرد) استفاده کنند، باید چیزی شبیه به این را در کد خود قرار می‌دادند:

پس از سال‌ها نیاز به تعریف انواع داده دقیق خودمان، کمیته استانداردهای C فایل هدر stdint.h را ایجاد کرد و آن را به بخشی از زبان تبدیل نمود.

اشاره‌گرهای توابع و typedef

زبان C به ما امکان استفاده از اشاره‌گرهای توابع را می‌دهد که در زمان استفاده از فراخوان‌ها (callback) کاربردی هستند. برای مثال، ممکن است بخواهیم به یک سیستم گرافیکی بگوییم که در زمان فشردن یک دکمه، تابع خاصی را فراخوانی کند. کد مربوط به این کار ممکن است شبیه به این باشد:

پارامتر functionToHandleButtonPress یک اشاره‌گر به تابعی است که یک عدد صحیح برمی‌گرداند و تنها یک آرگومان دریافت می‌کند که یک اشاره‌گر ثابت به یک رویداد است. این جمله کمی پیچیده است و زمانی که آن را به زبان C ترجمه کنیم، حتی پیچیده‌تر هم می‌شود:

مجموعه اول از پرانتزها الزامی هستند، زیرا بدون آن‌ها ما در حال تعریف تابعی هستیم که یک اشاره‌گر به عدد صحیح برمی‌گرداند:

به‌جای اینکه این قوانین پیچیده برای ترکیب زبان را به‌خاطر بسپاریم، بیایید با استفاده از typedef این ترکیب را ساده کنیم:

به این شکل تغییر می‌دهد:

typedef روشی برای سازماندهی انواع داده برای ساده‌سازی کد و همچنین واضح‌تر کردن آن فراهم می‌کند.

 

typedef و struct

همان‌طور که قبلاً دیدیم، می‌توانیم از struct برای تعریف یک نوع داده ساختار‌یافته استفاده کنیم.

برای استفاده از این ساختار، باید از کلیدواژه struct استفاده کنیم:

دستور typedef به ما این امکان را می‌دهد تا در استفاده از کلیدواژه struct اجتناب کنیم:

در این مثال، typedef به کامپایلر C می‌گوید که می‌خواهیم یک نوع داده جدید به نام rectangle تعریف کنیم.

برخی از برنامه‌نویسان بر این باورند که استفاده از typedef برای تعریف نوع داده structure باعث ساده‌تر و تمیزتر شدن کد می‌شود. برخی دیگر استفاده از struct را ترجیح می‌دهند؛ زیرا باعث می‌شود که به طور واضح مشخص شود یک متغیر از نوع structure است. این ترکیب اختیاری است، بنابراین هرکدام که برای شما بهتر کار می‌کند را انتخاب کنید..

اطلاعات
143
0
0
لینک و اشتراک
profile

Alireza Abbasi

متخصص الکترونیک

مقالات بیشتر
slide

پالت | بازار خرید و فروش قطعات الکترونیک

قطعات اضافه و بدون استفاده همیشه یکی از سرباره‌‌های شرکتها و طراحان حوزه برق و الکترونیک بوده و هست. پالت سامانه‌ای است که بصورت تخصصی اجازه خرید و فروش قطعات مازاد الکترونیک را فراهم می‌کند. فروش در پالت
family

آیسی | موتور جستجوی قطعات الکترونیک

سامانه آی سی سیسوگ (Isee) قابلیتی جدید و کاربردی از سیسوگ است. در این سامانه سعی شده است که جستجو، انتخاب و خرید مناسب تر قطعات برای کاربران تسهیل شود. جستجو در آیسی
family

سیسوگ‌شاپ | فروشگاه محصولات Quectel

فروشگاه سیسوگ مجموعه ای متمرکز بر تکنولوژی های مبتنی بر IOT و ماژول های M2M نظیر GSM، GPS، LTE، NB-IOT، WiFi، BT و ... جایی که با تعامل فنی و سازنده، بهترین راهکارها انتخاب می شوند. برو به فروشگاه سیسوگ
family

سیسوگ فروم | محلی برای پاسخ پرسش‌های شما

دغدغه همیشگی فعالان تخصصی هر حوزه وجود بستری برای گفتگو و پرسش و پاسخ است. سیسوگ فروم یک انجمن آنلاین است که بصورت تخصصی امکان بحث، گفتگو و پرسش و پاسخ در حوزه الکترونیک را فراهم می‌کند. پرسش در سیسوگ فرم
family

سیکار | اولین مرجع متن باز ECU در ایران

بررسی و ارائه اطلاعات مربوط به ECU (واحد کنترل الکترونیکی) و نرم‌افزارهای متن باز مرتبط با آن برو به سیکار
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
خانواده سیسوگ
سیسوگ‌شاپ

فروشگاه محصولات Quectel

پالت
سیسوگ فروم

محلی برای پاسخ پرسش‌های شما

سیسوگ جابز
سیسوگ
سیسوگ فروم
سی‌کار

اولین مرجع متن باز ECU در ایران

سیسوگ مگ
آی‌سی

موتور جستجوی قطعات الکترونیکی

سیسوگ آکادمی
پالت

بازار خرید و فروش قطعات الکترونیک

دیدگاه ها

become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله
become a writer

نویسنده شو !

سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.

ارسال مقاله