مطالب توسط masterdsp

10 نوع سنسور برتر در اینترنت اشیاء و کاربردهای آنها

10 نوع سنسور برتر در اینترنت اشیاء و کاربردهای آنها چیست؟من قصد دارم 10 حسگر برتر اینترنت اشیاء را که احتمالاً با آنها در طی فعالیت های خود  در زمینه IOT برخورد می کنید را برای شما معرفی کنم .همچنین مثالهایی از کاربردهای آنها در دنیای واقعی ذکر خواهم کرد همراه ما باشد.


سنسورهای دما :

در گذشته، سنسورهای دما مورد استفاده در اینترنت اشیا برای سیستم‌های گرما، تهویه و تهویه مطبوع (HVAC)، یخچال‌ها و سایر دستگاه‌های مشابه مورد استفاده برای کنترل محیطی مورد استفاده قرار می‌گرفتند. با این حال، ظهور اینترنت اشیاء نقش آن را گسترش داده است. امروزه می‌توانید سنسورهای دما را در صنایعی مانند تولید و کشاورزی و مراقبتهای پزشکی نیز پیدا کنید.

چگونه از این سنسورها در صنایع استفاده می شود؟ در فرآیند تولید، ماشین‌ آلات زیادی وجود دارند که هم به اندازه گیری دمای محیط خاص و هم به دمای دستگاه خاصی نیاز دارند. استفاده از حسگر دمای اینترنت اشیاء تضمین می کند که هر دوی اینها بهینه باقی می مانند.

وقتی صحبت از صنعت کشاورزی می شود، دمای خاک برای رشد محصول بسیار اهمیت پیدا می کند. پیش از این نظارت بر این یک فرآیند به صورت دستی و بسیار خسته کننده بود. اکنون با پیشرفت تکنولوژی، سنسورهای دما نظارت و کنترل از راه دور را از طریق یک برنامه IoT آسان تر می کنند. استفاده از روشهای مدرن به  تولید انبوه گیاهان کمک شایانی میکند.

شرکتهای زیادی سنسورهای دما با کاربردهای IOT تولید میکنند که چند نمونه از شناخته شده ترین آنها شرکتهای زیر هستند :


سنسورهای فشار :

سنسور فشار در حوزه اینترنت اشیاء به هر وسیله ای که فشار را حس کرده و بتواند آن را به سیگنال الکتریکی تبدیل کند گفته میشود. سطح ولتاژ داده شده توسط سنسور به سطح فشار اعمال شده بستگی دارد.

این حسگرها سیستم‌های اینترنت اشیا را قادر می‌سازند که سیستم‌ها و دستگاه‌هایی را که تحت فشار هستند، نظارت کنند. اگر انحراف از محدوده فشار استاندارد وجود داشته باشد، دستگاه مشکل را به مدیر اطلاع می دهد.

سنسورهای فشار معمولاً در کاربردهای مدیریت منابع آب و یا سیستم های گرمایش یافت می شوند و استفاده می شوند. این کاربرد به این دلیل است که آنها به راحتی می توانند هر گونه نوسان یا افت فشار را تشخیص دهند. با این حال، سنسورهای فشار در صنعت تولید نیز استفاده می شوند.

با استفاده از فشار مناسب شما میتوانید انواع فشار چه مکانیکی چه پنوماتیکی چه فشار هوا هم به صورت دینامیک و هم به صورت استاتیک  را اندازه گیری نمایید.

سنسورهای فشار هوا استفاده بسیار گسترده و حیاتی در صنایع پروازی دارند.

در ادامه میتوانید لیست چند شرکت مطرح تولید کننده سنسورهای فشار را مشاهده نمایید.


شتاب سنج ها :

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

بیشتر شتاب سنج های موجود از تکنولوژی MEMS برای اندازه گیری شتاب استفاده میکنند.

اندازه گیری شتاب و استخراج داده های موردنیاز با دقت بالا به خاطر ماهیت مکانیکی سنسورهای MEMS کاری پیچیده و نیازمند محاسبات بسیاری میباشد. در نتیجه طراحی و ساخت یک شتاب سنج با دقت بالا دارای ارزش افزوده زیادی خواهد بود.

علاوه بر شتاب، شتاب سنج می تواند تغییرات گرانش را نیز تشخیص دهد. کاربردهای معمول شتاب‌سنج‌ها در اینترنت اشیا شامل گام‌سنج‌های هوشمند و نظارت بر ناوگان رانندگی است. با این حال، در حال حاضر در میلیون ها دستگاه از جمله گوشی های هوشمند وجود دارند.

همچنین می توان از آنها برای محافظت در برابر سرقت استفاده کرد. اگر جسمی که باید ثابت باشد حرکت کند، شتاب‌سنج‌ها به سیستمی که در آن استفاده می‌شود هشدار می‌دهند.

از جمله تولید کنندگان مطرح سنسورهای شتاب سنج میتوان شرکتهای زیر را نام برد.


سنسورهای مجاورتی :

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

این سنسورهای پرکاربرد در اینترنت اشیاء اغلب در صنعت خرده فروشی یافت می شوند. دلیل آن اینست که آنها می توانند حرکت و ارتباط بین مشتریان و محصولی که ممکن است به آن علاقه مند شوند را تشخیص دهند. در عوض، کاربر می تواند از هر تخفیف، پیشنهادات ویژه یا محصولات مشابهی که در نزدیکی سنسور قرار دارد مطلع شود.

سنسورهای مجاورت همچنین ممکن است در پارکینگ‌های مراکز خرید، استادیوم‌ها یا فرودگاه‌ها برای نشان دادن مکان‌های پارک موجود نیز استفاده شوند.

شرکتهای معتبر تولید کننده سنسورهای مجاورتی را در زیر میتوانید بررسی کنید.


سنسورهای رطوبت سنج:

سنسورهای رطوبت در IoT میزان بخار آب موجود در هوا را اندازه گیری می کنند. از نظر علمی، رطوبت نسبی (RH) را اندازه گیری می کنند.

این نوع سنسور معمولاً به همراه  حسگرهای دما هنگامی که یک فرآیند تولید به شرایط کاری بهینه و کامل نیاز دارد استفاده می شود.

سنسورهای رطوبت معمولاً در سیستم های گرمایش، تهویه و تهویه مطبوع (HVAC) یافت می شوند .همچنین در محیط خانه و هم در محیط های تجاری. با این حال، مراکز هواشناسی نیز از آنها برای گزارش و پیش بینی آب و هوا استفاده می کنند.

شرکتهای معتبر تولید کننده سنسورهای رطوبت که میتونم نام ببرم رو در زیر لیست کردم.


سنسور تصویر :

حسگرهای تصویر IoT برای تبدیل تصاویر به سیگنال های الکترونیکی استفاده می شوند. سپس دیتاهای دریافتی یا نمایش داده می شوند یا به فایل های الکترونیکی تبدیل و ذخیره می شوند.

بیشترین استفاده از سنسورهای تصویر در دوربین های دیجیتال و ماژول های وای فای اینترنت اشیا است.

استفاده از دیتای سنسورهای تصویر نیازمند پردازش تصویر میباشد. این سنسورها در کاربردهای اینترنت اشیاء صنعتی (IIOT) و هوش مصنوعی اشیاء (AIOT)  به شدت مورد توجه و استفاده میباشند.

در زیر نام تعدادی از  تولید کننده های سنسورهای تصویر آورده شده است.


سنسور اندازه گیری سطح :

سنسورهای سطح برای تشخیص سطوح انواع خاصی از اشیاء و در واقع مواد استفاده می شوند. این مواد شامل مایعات، مواد دانه ای و پودرها می شود.

همانطور که قابل تصور است، این نوع سنسورها کاربردهای مفیدی دارند و در بسیاری از صنایع و کاربردهای مختلف استفاده می شود. این کاربردها شامل:

تولید روغن
تولید نوشیدنی
تولید مواد غذایی
تصفیه آب

تعدادی از تولید کننده های سنسورهای سطح در زیر لیست شده اند.


سنسور گاز :

سنسورهای گاز تغییرات هوا را کنترل و تشخیص می دهند. این حسگرها برای ایمنی ما حیاتی هستند زیرا قادر به تشخیص وجود گازهای بالقوه مضر یا حتی سمی هستند.

سنسورهای گاز بیشتر در تحقیقات معدنی، نفت و گاز و شیمیایی استفاده می شود. با این حال، حسگرهای گاز نیز در اکثر خانه ها از طریق آشکارسازهای دی اکسید کربن شناخته میشود.

تعدادی از تولید کننده های سنسورهای گاز در زیر لیست شده اند.


سنسورهای مادون قرمز :

یک سنسور مادون قرمز – که به عنوان سنسور IR شناخته می شود – ویژگی های محیط اطراف خود را اسکن و حس می کند. این کار را با گسیل یا تشخیص اشعه مادون قرمز انجام می گیرید. علاوه بر این، این حسگرهای اینترنت اشیا قادر به اندازه گیری گرمای خارج شده از اجسام نیز هستند.

سنسورهای مادون قرمز را می توان برای چندین کاربرد مختلف اینترنت اشیا استفاده کرد.با این حال، رایج ترین استفاده از آنها در صنعت مراقبت های بهداشتی می باشد. به عنوان مثال، سنسورهای مادون قرمز را می توان برای نظارت بر جریان خون یا فشار خون استفاده کرد.

تعدادی از تولید کننده های سنسورهای مادون قرمز در زیر امده است.


سنسورهای آشکارساز حرکت :

این سنسورنباید با سنسورهای مجاورت اشتباه گرفته شود، سنسورهای تشخیص حرکت برای تشخیص حرکت فیزیکی در یک منطقه خاص استفاده می شوند.

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

علاوه بر امنیت، این حسگرهای اینترنت اشیا را می‌توان در بسیاری از دستگاه‌های ساختمان‌های تجاری مدرن نیز یافت. این شامل:

تعدادی از تولید کننده های سنسورهای مادون قرمز در زیر امده است.

گیت های تردد خودرو
سینک اتوماتیک، خشک کن دست، و حوله پخش کن
سیستم های مدیریت انرژی

اتاق های سرور

ممنون که تا انتهای این مقاله با ما بودید.

پیج ما را در اینستاگرام دنبال کنید و از انتشار جدیدترین مقالات زودتر از بقیه با خبر شوید.

کلاس های ذخیره سازی در C


کلاس های ذخیره سازی در C :

این آموزش در ادامه آموزشهای قبلی پیرامون زبان برنامه نویسی C میباشد. در قسمت قبل در مورد متغیرها در زبان C صحبت کردیم.در این آموزش قصد داریم به بررسی کلاس های ذخیره سازی در C بپردازیم با ما همراه باشید.

قبل از دامه آموزش ابتدا به سرعت تفاوت بین طول عمر و محدوده یک متغیر را با هم بررسی میکنیم.

محدوده متغیر:

محدوده یک متغیر در C به بخشی از یک برنامه اشاره می کند که در آن متغیر قابل دسترسی و استفاده است. به عبارت ساده، این محدوده قابل مشاهده بودن متغیر را تعریف میکند.

طول عمر متغیر:

در برنامه نویسی C، “طول عمر” یک متغیر به مدت یا وجود آن در طول اجرای یک برنامه اشاره دارد. متغیرها در C بر اساس محدوده و کلاس ذخیره سازی، طول عمر متفاوتی دارند.


دامنه متغیرها :

محدوده

تعریف

محدوده فایل

از ابتدای فایل (که واحد ترجمه نیز نامیده می شود) شروع می شود و در انتهای فایل به پایان می رسد. این دامنه به شناسه هایی اشاره دارد که خارج از همه توابع اعلام شده اند. شناسه دامنه فایل در کل فایل قابل مشاهده است. متغیرهایی که دامنه فایل دارند متغیرهای سراسری یا گلوبال هستند.

محدوده بلاک

با باز کردن { یک بلوک شروع می شود و با بسته شدن مربوط به آن } پایان می یابد. با این حال، محدوده بلوک به پارامترهای تابع در تعریف تابع نیز گسترش می یابد. یعنی پارامترهای تابع در محدوده بلوک یک تابع گنجانده شده است. متغیرهای دارای محدوده بلوک برای بلوک خود محلی یا لوکال هستند.

محدوده پروتو تایپ تابع

شناسه های اعلام شده درپروتو تایپ تابع. فقط در پروتو تایپ قابل مشاهده است.

محدوده تابع

با باز کردن { یک تابع شروع می شود و با بسته شدن آن } پایان می یابد. دامنه تابع فقط برای برچسب ها اعمال می شود.وقتی یک برچسب به عنوان هدف دستور goto استفاده می شود آن برچسب باید در همان تابع goto باشد.


کلاس های ذخیره سازی در C :

در زبان C، طول عمر و محدوده یک متغیر توسط کلاس های ذخیره سازی در C تعریف می شود.

چهار کلاس ذخیره سازی در زبان c وجود دارد :

  • کلاس اتوماتیک Auto :

  • رجیستر (Register) :

  • کلاس Eternal (extern) :

  • کلاس satic :

کلاس ذخیره سازی auto :

ویژگیها :

محل ذخیره سازی

حافظه

محدوده

محلی / بلاک

طول عمر

تا هنگامیکه کنترل برنامه داخل بلاک میباشد.

مقدار اولیه پیشفرض

یک مقدار تصادفی

کلاس های ذخیره سازی auto در C کلاس ذخیره سازی پیش فرض برای همه متغیرهای محلی هستند.

کلاس ذخیره سازی رجیستر :

ویژگیها :

				
					{
  int mount;
  auto int month;
}
				
			

مثال بالا دو متغیر را در یک کلاس ذخیره سازی تعریف می کند. به طور پیش فرض، همه متغیرهای محلی خودکار هستند. «خودکار» فقط در توابع، یعنی متغیرهای محلی قابل استفاده است.

محل ذخیره سازی

رجیسترهای CPU

محدوده

محلی در بلاک

طول عمر

تا هنگامیکه کنترلر برنامه داخل بلاک یا تابع میباشد.

مقدار اولیه

تصادفی

یک مقدار ذخیره شده در یک ثبات CPU همیشه سریعتر از مقدار ذخیره شده در حافظه قابل دسترسی است. بنابراین، اگر متغیری در بسیاری از مکان‌های یک برنامه استفاده می‌شود، بهتر است کلاس ذخیره‌سازی آن را ثبات اعلام کنیم.

هیچ تضمینی وجود ندارد که ما متغیری را به عنوان ثبات اعلام کرده باشیم و در ثبات CPU ذخیره شود! چرا؟ دلیل آن این است که رجیسترهای CPU محدود هستند و ممکن است مشغول انجام کارهای دیگری باشند. در آن صورت، آن متغیر به عنوان کلاس ذخیره سازی پیش فرض در C یعنی کلاس ذخیره سازی خودکار کار می کند.

نکته: اینکه آیا هر متغیری در رجیستر CPU ذخیره می شود یا نه به ظرفیت ریزپردازنده بستگی دارد. به عنوان مثال، اگر ریزپردازنده دارای یک ثبات 16 بیتی باشد، نمی تواند مقدار شناور یا مقدار دوگانه را نگه دارد که به ترتیب به 4 و 8 بایت نیاز دارند. با این حال، اگر از کلاس ذخیره سازی register برای متغیر float یا double استفاده کنید، هیچ پیام خطایی دریافت نمی کنید زیرا کامپایلر آن را به عنوان کلاس ذخیره سازی پیش فرض یعنی کلاس ذخیره سازی خودکار در نظر می گیرد.

در حلقه هایی که از یک متغیر بارها و بارها استفاده میشود بهتر است آن متغیر از نوع کلاس register تعریف شود.

کلاس ذخیره سازی extern :

ویژگیها :

 

محل ذخیره سازی

حافظه

محدوده

سراسری / فایل

طول عمر

تا هنگامیکه برنامه در حال اجراست.

مقدار اولیه

صفر

کلمه کلیدی extern ، کلاس ذخیره سازی extern متغیر اعلام شده را نشان میدهد. استفاده اصلی از extern این است که نشان میدهد متغیر در جای دیگری از برنامه اعلان شده است. برای درک اینکه چرا این نکته مهم است، لازم است تفاوت بین یک اعلان و یک تعریف را درک کنیم. یک اعلان نام و نوع یک متغیر یا تابع را اعلام می کند. یک تعریف باعث می‌شود که فضای ذخیره‌سازی برای متغیر یا بدنه تابع تعریف شده تخصیص داده شود. یک متغیر یا تابع ممکن است اعلان های زیادی داشته باشد، اما تنها یک تعریف برای آن متغیر یا تابع می تواند وجود داشته باشد.

هنگامی که از کلمه کلیدی extern با اعلان متغیر استفاده می شود، هیچ فضای ذخیره ای به آن متغیر اختصاص داده نمی شود و فرض می شود که متغیر قبلاً در جای دیگری از برنامه تعریف شده است. وقتی از کلمه کلیدی extern استفاده می کنیم، متغیر نمی تواند مقداردهی اولیه شود، زیرا با کلمه کلیدی extern ، متغیر اعلان می شود، نه تعریف.

در نمونه برنامه C زیر، اگر extern int x را حذف کنید. با خطای «Undeclared identifier ‘x’» مواجه خواهید شد زیرا متغیر x دیرتر از زمانی که در printf استفاده شده است تعریف شده است. در این مثال، extern به کامپایلر می‌گوید که متغیر x قبلاً تعریف شده است و در اینجا برای اطلاعات کامپایلر اعلان می‌شود.

				
					#include <stdio.h>

extern int x;

int main()
{
    printf("x: %d\n", x);
}

int x=10;
				
			

همچنین، اگر عبارت extern int x را تغییر دهید. به ;extern int x = 50 شما دوباره با خطای “تعریف مجدد “x” مواجه خواهید شد زیرا با استفاده از extern متغیر اگر در جای دیگری تعریف شده باشد نمی تواند مقداردهی اولیه شود.

اغلب کلمه کلیدی extern زمانی استفاده می شود که بخواهیم متغیر سراسری را در دو یا چند فایل .c به اشتراک بگذاریم.

توجه داشته باشید که extern را می توان برای یک اعلان تابع نیز اعمال کرد، اما انجام این کار تاثیری ندارد زیرا همه اعلان های تابع به طور ضمنی خارجی هستند.

متغیرهای static :

ویژگیها

محل ذخیره سازی

حافظه

محدوده

بلاک

طول عمر

مقدار متغیر بین فراخوانی های تابع مختلف باقی می ماند

مقدار اولیه

صفر

متغیرهای استاتیک هم بر طول عمر و هم بر دامنه تأثیر می گذارند.

تاثیر بر روی طول عمر :

متغیرهای ثابت آن دسته از متغیرهایی هستند که طول عمر آنها مانند متغیرهای سراسری برابر با طول عمر برنامه باقی می ماند. هر متغیر محلی یا سراسری را می توان بسته به آنچه که منطق از آن متغیر انتظار دارد، ثابت کرد.مثال زیر را در نظر بگیرید :

				
					#include<stdio.h>

char** func_Str();

int main(void)
{
  char **ptr = NULL;
  ptr = func_Str();
  printf("\n [%s] \n",*ptr);
  return 0;
}

char** func_Str()
{
  char *p = "Linux";
  return &p;
}
				
			

در کد بالا، تابع “()func_str” آدرس اشاره گر “p” را به تابع فراخوانی برمی گرداند که از آن برای چاپ رشته “Linux” برای کاربر از طریق “()printf” استفاده می کند. بیایید به خروجی نگاه کنیم:

				
					$ ./static
[Linux]
$
				
			

خروجی بالا مطابق انتظار است. خب، همه چیز به نظر خوب است؟ اما، یک مشکل پنهان در کد وجود دارد. به طور خاص، مقدار بازگشتی اشاره گر، کاراکتر محلی (char *p) در تابع “()func_Str” است. مقداری که برگردانده می شود آدرس متغیر اشاره گر محلی «p» است. از آنجایی که ‘p’ برای تابع محلی است، بنابراین به محض بازگشت تابع، طول عمر این متغیر به پایان می رسد و از این رو مکان حافظه آن برای سایر عملیات آزاد می شود.

البته به این نکته هم دقت کنید که کد بالا در IDE اجرا نمیشود و با هشدار روبرو میگردد.

ولی برای اینکه این نکته رو متوجه بشید یک مثال دیگه هم میزنم :

 

				
					#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
  char **ptr1 = NULL;
  char **ptr2 = NULL;
  
  ptr1 = func1_Str();
  printf("\n [%s] \n",*ptr1);
  
 ptr2 = func2_Str();
 printf("\n [%s] \n",*ptr2);
 
 printf("\n [%s] \n",*ptr1);

return 0;
}

char** func1_Str()
{
  char *p = "Linux";
  return &p;
}

char** func2_Str()
{
  char *p = "Windows";
  return &p;
}
				
			

در کد بالا، اکنون دو تابع “()func1_Str” و “()func2_Str” وجود دارد. مشکل منطقی در اینجا نیز به همان شکل باقی می ماند. هر یک از این توابع آدرس متغیر محلی خود را برمی گرداند. در تابع ()main، آدرس برگردانده شده توسط ()func1_Str برای چاپ رشته “Linux” (همانطور که توسط متغیر اشاره گر محلی آن اشاره شده است) و آدرس برگردانده شده توسط تابع ()fuc2_Str برای چاپ رشته استفاده می شود. Windows’ (همانطور که توسط متغیر اشاره گر محلی آن اشاره شده است). یک قدم جلوتر به سمت انتهای تابع ()main و با استفاده مجدد از آدرسی که توسط ()func1_Str برای چاپ رشته “Linux” بازگردانده شده ()printf را اجرا میکنیم.

خروجی رو ببینیم با هم :

				
					$ ./static
[Linux]
[Windows]
[Windows]
				
			

خروجی بالا مطابق انتظار نیست. چاپ سوم باید «لینوکس» به جای «ویندوز» باشد. خوب، بهتر است بگویم که خروجی بالا مورد انتظار بود.با این سناریوی مشکل کد را بهتر متوجه شدیم.

حالا اجازه دهید کمی عمیق تر برویم تا ببینیم پس از بازگشت آدرس متغیر محلی چه اتفاقی افتاده است.

کد زیر را ببینید:

				
					#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
  char **ptr1 = NULL;
  char **ptr2 = NULL;
  
  ptr1 = func1_Str();
  printf("\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n",*ptr1,(void*)func1_Str,(void*)ptr1);

  ptr2 = func2_Str();
  printf("\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n",*ptr2,(void*)func2_Str,(void*)ptr2);
  printf("\n [%s] [%p]\n",*ptr1,(void*)ptr1);

  return 0;
}

char** func1_Str()
{
  char *p = "Linux";
  return &p;
}

char** func2_Str()
{
  char *p = "Windows";
  return &p;
}
				
			

کد بالا برای چاپ آدرس توابع و آدرس متغیرهای اشاره گر محلی مربوطه اصلاح شده است.

خروجی به صورت زیر خواهد بود :

				
					$ ./static
[Linux] :: func1_Str() address = [0x4005d5], its returned address is [0x7fff705e9378]
[Windows] :: func2_Str()address = [0x4005e7], its returned address is [0x7fff705e9378]
[Windows] [0x7fff705e9378]
				
			

خروجی بالا روشن می کند که زمانی که طول عمر متغیر محلی تابع “()func1_Str” به پایان برسد، همان آدرس حافظه برای متغیر اشاره گر محلی تابع “()func2_Str” استفاده میشود از این رو چاپ سوم  “ویندوز” است و نه “لینوکس”.

بنابراین، اکنون می بینیم که ریشه مشکل طول عمر متغیرهای اشاره گر است. اینجاست که کلاس ذخیره سازی «استاتیک» به کمک می آید. همانطور که قبلاً بحث شد، کلاس های ذخیره سازی استاتیک طول عمر یک متغیر را برابر با عمر برنامه می کند. بنابراین، بیایید متغیرهای اشاره گر محلی را ثابت کنیم و سپس خروجی را ببینیم:

				
					#include<stdio.h>

char** func1_Str();
char** func2_Str();

int main(void)
{
  char **ptr1 = NULL;
  char **ptr2 = NULL;

  ptr1 = func1_Str();
  printf("\n [%s] :: func1_Str() address = [%p], its returned address is [%p]\n",*ptr1,(void*)func1_Str,(void*)ptr1);

  ptr2 = func2_Str();
  printf("\n [%s] :: func2_Str()address = [%p], its returned address is [%p]\n",*ptr2,(void*)func2_Str,(void*)ptr2);
  printf("\n [%s] [%p]\n",*ptr1,(void*)ptr1);

  return 0;
}

char** func1_Str()
{
  static char *p = "Linux";
  return &p;
}

char** func2_Str()
{
  static char *p = "Windows";
  return &p;
}
				
			

توجه داشته باشید که در کد بالا، اشاره گرها  با کلاس static ساخته شده اند. در این حالت خروجی به صورت زیر است :

				
					$ ./static
[Linux] :: func1_Str() address = [0x4005d5], its returned address is [0x601028]
[Windows] :: func2_Str()address = [0x4005e0], its returned address is [0x601020]
[Linux] [0x601028]
				
			

تاثیر بر دامنه :

در مواردی که کد در چندین فایل پخش می شود، می توان از نوع ذخیره سازی استاتیک برای محدود کردن دامنه یک متغیر به یک فایل خاص استفاده کرد. به عنوان مثال، اگر در یک فایل یک متغیر ‘count’ داشته باشیم و بخواهیم متغیر دیگری با همین نام در فایل دیگری داشته باشیم، در آن صورت، یکی از متغیرها باید ثابت شود.

مثال زیر این موضوع را نشان می دهد:

static.c

				
					#include<stdio.h>

int count = 1;

int main(void)
{
  printf("\n count = [%d]\n",count);
  return 0;
}
				
			

static_1.c

				
					#include<stdio.h>

int count = 4;

int func(void)
{
  printf("\n count = [%d]\n",count);
  return 0;
}
				
			

اکنون، زمانی که هر دو فایل کامپایل شده و به یکدیگر پیوند داده می شوند تا یک فایل اجرایی واحد تشکیل دهند،  خطایی وجود دارد که توسط GCC اعلان می شود:

				
					$ gcc -Wall static.c static_1.c -o static
/tmp/ccwO66em.o:(.data+0x0): multiple definition of `count'
/tmp/ccGwx5t4.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
$
				
			

بنابراین، می بینیم که GCC از اعلان های متعدد متغیر «شمارش» اشکال میگیرد.

به عنوان یک اقدام اصلاحی، این بار یکی از متغیرهای “count” از نوع static تعریف میشود:

static.c

				
					#include<stdio.h>

static int count = 1;

int main(void)
{
  printf("\n count = [%d]\n",count);
  return 0;
}
				
			

static_1.c

				
					#include<stdio.h>

int count = 4;

int func(void)
{
  printf("\n count = [%d]\n",count);
  return 0;
}
				
			

اکنون، هر دو فایل کامپایل شده و با هم پیوند داده می شوند:

				
					$ gcc -Wall static.c static_1.c -o static
$
				
			

بنابراین، می بینیم که این بار هیچ خطایی ایجاد نمی شود زیرا static دامنه متغیر “count” در فایل static.c را به خود فایل محدود کرده است.

توابع استاتیک :

به طور پیش فرض هر تابعی که در یک فایل C تعریف شده باشد extern است. این بدان معنی است که تابع را می توان در هر فایل منبع دیگری از همان کد/پروژه (که به عنوان یک واحد ترجمه جداگانه کامپایل می شود) استفاده کرد. حال، اگر شرایطی وجود داشته باشد که دسترسی به یک تابع به فایلی که در آن تعریف شده است محدود شود یا اگر تابعی با همان نام در فایل دیگری از همان کد/پروژه مورد نظر باشد،  آن توابع را در C می توان استاتیک کرد.

با بسط دادن همان مثالی که در بخش قبل استفاده شد، فرض کنید دو فایل داریم:

static.c

				
					#include<stdio.h>

void func();

int main(void)
{
  func();
  return 0;
}

void funcNew()
{
  printf("\n Hi, I am a normal function\n");
}
				
			

static_1.c

				
					#include<stdio.h>

void funcNew();

int func(void)
{
  funcNew();
  return 0;
}
				
			

اگر کد بالا را کامپایل و اجرا کنیم خواهیم داشت :

				
					$ gcc -Wall static.c static_1.c -o static
$ ./static
Hi, I am a normal function
$
				
			

بنابراین، می بینیم که تابع ()funcNew در یک فایل تعریف شده و با موفقیت از فایل دیگر فراخوانی شده است. حال، اگر فایل static_1.c بخواهد ()funcNew خودش را داشته باشد، یعنی:

static_1.c

				
					#include<stdio.h>

void funcNew();

int func(void)
{
  funcNew();
  return 0;
}

void funcNew()
{
  printf("\n Hi, I am a normal function\n");
}
				
			

حال، اگر هر دو فایل کامپایل شده و با هم پیوند داده شوند:

				
					$gcc -Wall static.c static_1.c -o static
/tmp/ccqI0jsP.o: In function `funcNew':
static_1.c:(.text+0x15): multiple definition of `funcNew'
/tmp/ccUO2XFS.o:static.c:(.text+0x15): first defined here
collect2: ld returned 1 exit status
$
				
			

بنابراین، می بینیم که کامپایلر از تعاریف متعدد تابع ()fucNew  ارور میگیرد. بنابراین،

حالا ()funcNewرا در static_1.c به صورت static اعلان میکینم:

				
					#include<stdio.h>

static void funcNew();

int func(void)
{
  funcNew();
  return 0;
}

static void funcNew()
{
  printf("\n Hi, I am also a normal function\n");
}
				
			

حالا اگر کد را کامپایل کنیم، می بینیم که کامپایلر هرگز خطایی نمیگیرد :

				
					$ gcc -Wall static.c static_1.c -o static
$ ./static
Hi, I am also a normal function
$
				
			

متغیرها در زبان C


متغیرها در زبان C

این مقاله ادامه آموزش زبان برنامه نویسی c می باشد و بحث برنامه نویسی زبان C و پیاده سازی آن را در بر می گیرد. در آخرین آموزش ما Datatypes را در برنامه نویسی C دیده ایم. در این مقاله یکی از مفاهیم اساسی برنامه C که متغیرها در زبان C است را توضیح می دهیم. هدف این آموزش ارائه مثال های آسان و کاربردی برای درک بهتر برنامه نویسی C است.

زمانی که می خواهیم برنامه نویسی زبان C را یاد بگیریم، باید از اصول اولیه شروع کنیم. ابتدا باید متغیرهای زبان C را درک کنیم.


متغیرها در برنامه نویسی C چیست؟

قبل از ادامه  مقاله ، بهتره که به سرعت تفاوت بین طول عمر و محدوده یک متغیر را درک کنیم.

در برنامه نویسی C از متغیرها برای ذخیره موقت داده ها استفاده می شود. متغیرها مانند ظرف هایی هستند که انواع مختلفی از اطلاعات مانند اعداد، کاراکترها یا آرایه ها را در خود جای می دهند.

متغیر یک نام سفارشی تعریف شده توسط کاربر است که به یک مکان حافظه اختصاص داده شده است که به ذخیره برخی داده ها یا مقادیر مانند اعداد، کاراکترها و غیره کمک می کند. در نظر داشته باشید که شما نمی توانید نام کلمه کلیدی را به عنوان نام متغیر اعلام کنید. متغیرها در C با یک نوع داده خاص اعلان می شوند. می تواند انواع مختلفی از داده ها را بر اساس نوع داده در متغیر ذخیره کند و مقدار آن در طول برنامه تغییر کند و همچنین می توان از همان متغیر بارها در طول اجرای برنامه استفاده مجدد کرد.

اندازه متغیر بستگی به نوع داده ای دارد که ذخیره می کند. هر متغیر دارای یک نوع است که به کامپایلر می گوید که ناحیه حافظه چقدر بزرگ است و چگونه با بیت هایی که در آن ناحیه ذخیره می شوند در حین انجام انواع مختلف عملیات رفتار کند. اگر این مقاله را مرور کنید، با اندازه های هر نوع داده و نحوه ذخیره داده ها در حافظه یا متغیر آشنا خواهید شد.

Syntax :

 

				
					datatype variable_name = value;


				
			

قوانین تعریف متغیر ها در زبان C:

  • نام متغیر فقط شامل حروف الفبا، اعداد و زیرخط است.

  • نام متغیر باید با خط زیر یا حروف الفبا شروع شود.

  • از کلمات کلیدی نمیتوان به عنوان نام متغیر استفاده کرد.

  • کاراکترها و فاصله های خاص در نام متغیر مجاز نیستند.

هنگام انجام برنامه نویسی همیشه باید قوانین بالا را رعایت کنید.

نامهای معتبر

نامهای نا معتبر

;int name

; int 2

;char a = 'c'

;char goto

;float sum_result;

;double x y

سعی کنید هنگام نامگذاری برای متغیرها از اسامی معنی دار و مرتبط استفاده نمایید این کار کمک بسیار زیادی به خوانایی برنامه شما میکند.

مثال :

				
					#include <stdio.h>

int main() 
{
    int sum = 5;   //here sum is a variable and 5 is the initial value.
    
    printf("Value is %d", sum);
    
    return 0;
}
				
			

خروجی :

				
					Value is 5
				
			


انواع متغیرها در برنامه نویسی C :

به طور معمول میتوان متغیرها را به دو دسته کلی طبقه بندی کرد.

  • متغیر های محلی یا Local

  • متغیر های سراسری یا Global

خب بیاید با هم ویژگیهای هر کدوم رو با هم بررسی کنیم.

متغیر های محلی :

متغیری که در داخل یک بلوک اعلان می شود به عنوان متغیر محلی شناخته می شود. محدوده یک متغیر در بلوکی که در آن اعلان شده است در دسترس است. متغیرهای محلی فقط با دستورات داخل همان بلوک که در آن اعلان شده اند قابل دسترسی هستند. طول عمر یک متغیر زمانی شروع می شود که اجرای کد وارد بلوک شده و در هنگام خروج از بین می رود. متغیرها معمولا در یک پشته  (stack)ذخیره می شوند مگر اینکه جای دیگری برای ذخیره سازی مشخص شده باشند.

مثال 1:

				
					#include <stdio.h>
int main()
{
    int a=5; // local variable
    
    printf("Value of A = %d",a);
    
    return 0;
}
				
			

در برنامه فوق int a در تابع main تعریف شده است. بنابراین، یک متغیر محلی برای تابع main میباشد. ما نمی توانیم از خارج از تابع اصلی به متغیر a دسترسی داشته باشیم.

مثال 2 :

				
					#include <stdio.h>

int main()
{
  int a=5; // local variable,   dspworld.ir can be accessed only from main function

  if( a == 5 )
  {
    int b = 10; // local variable, can be accessed only from if condition block
    b = 12;
    printf("Value of B = %d\n",b);
    printf("(Inside If) Value of A = %d\n",a);
  }    

  //here we cannot acceess the variable b dspworld.ir

  printf("Value of A = %d\n",a);
  
  return 0;
}
				
			

در برنامه فوق int a در تابع main تعریف شده است. بنابراین، این یک متغیر محلی برای تابع main است.  در این برنامه نمی توانیم از خارج از تابع main به متغیر a دسترسی پیدا کنیم. و int b در داخل شرط ()if تعریف شده است. در نتیجه، ما فقط می توانیم از داخل ()if به آن دسترسی داشته باشیم.

خروجی :

				
					Value of B = 12
(Inside If) Value of A = 5
Value of A = 5
				
			

مثال 3 :

				
					#include <stdio.h>

int main()
{
  int a=5; // local variable, can be accessed only from main function

  if( a == 5 )
  {
    int a = 10; // local variable with same name, can be accessed only from if condition block
    printf("(Inside If) Value of A = %d\n",a);
  } 

  printf("Value of A = %d\n",a);
  
  return 0;
}
				
			

در برنامه فوق int a در تابع main تعریف شده است. بنابراین، یک متغیر محلی برای تابع main است. ما نمی توانیم از خارج از تابع اصلی به این متغیر a دسترسی پیدا کنیم. و یک int دیگر در داخل شرط ()if تعریف شده است. در این حالت، ()if از متغیری استفاده خواهد کرد که در داخل ()if تعریف شده است.  در نتیجه نمی تواند به int a که در تابع main تعریف شده است دسترسی پیدا کند. زیرا کامپایلر به متغیر محلی که اخیراً ایجاد شده است اولویت خواهد داد.

				
					(Inside If) Value of A = 10
Value of A = 5
				
			

متغیر های سراسری یا global :

در زبان برنامه نویسی C، متغیرهای سراسری متغیرهایی هستند که توسط هر تابع یا بلوک کد در یک برنامه قابل دسترسی و تغییر هستند. آنها خارج از هر تابعی، معمولاً در بالای یک فایل، اعلان می شوند و دامنه سراسری دارند. این بدان معنی است که آنها می توانند در کل برنامه استفاده شوند. با این حال، توجه به این نکته ضروری است که استفاده از متغیرهای سراسری باید با احتیاط انجام شود، زیرا می توانند منجر به مسائل بالقوه ای مانند نام های تکراری و مشکلات در ردیابی تغییرات متغیر شوند.

مثال :

				
					#include <stdio.h>

int a = 10; // global variable

int fun() 
{
  printf("(func)Value = %d\n", a);
}
int main()
{
  fun();
  printf("(main)Value = %d\n", a);
  return 0;
}
				
			

در برنامه فوق، متغیر سراسری ‘a’ را ایجاد کرده ایم. به این متغیر میتوتن در هر نقطه از برنامه دسترسی داشت و مقدار آن را تغییر داد. اگر بخواهیم از فایل دیگری در همان برنامه به این متغیر دسترسی داشته باشیم، باید از کلمه کلیدی extern استفاده کنیم.

				
					(func)Value = 10
(main)Value = 10
				
			


سوالات متداول :

  • آیا می توانیم مقدار متغیر را هر چند بار در برنامه C تغییر دهیم؟

    بله، مقدار یک متغیر را می توان چندین بار در یک برنامه C تغییر داد. برای مرجع خود برنامه زیر را ببینید.

  • آیا مقدار اولیه همیشه هنگام ایجاد متغیرها در C مورد نیاز است؟

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

  • اگر متغیر در زمان اعلام هیچ مقدار اولیه ای نداشته باشد، مقدار اولیه متغیر چقدر است؟

    اگر متغیری در زمان اعلام مقدار اولیه نداشته باشد و یک متغیر محلی باشد، دارای مقدار اولیه تعریف نشده (مقدار Garbage) خواهد بود. اگر متغیری در زمان اعلان مقدار اولیه نداشته باشد و یک متغیر سراسری باشد، دارای مقدار اولیه صفر (0) خواهد بود.

  • آیا می توانیم چندین متغیر محلی با یک نام در C ایجاد کنیم؟

    خیر، در زبان برنامه نویسی C، نمی توانید چندین متغیر محلی با یک نام در یک محدوده ایجاد کنید. هر متغیر در محدوده باید یک نام منحصر به فرد داشته باشد تا از ابهام جلوگیری شود و از اجرای صحیح برنامه اطمینان حاصل شود. اگر بخواهید چندین متغیر را با یک نام در یک محدوده اعلام کنید، منجر به خطای کامپایل می شود. مهم است که نام های معنی دار و متمایز برای متغیرها انتخاب کنید تا کد شما خواناتر و قابل نگهداری تر شود.

  • آیا می توانیم یک متغیر محلی و یک متغیر سراسری با نام یکسان در C ایجاد کنیم؟

    بله، امکان ایجاد یک متغیر محلی و یک متغیر سراسری با همین نام در زبان برنامه نویسی C وجود دارد. با این حال، انجام این کار توصیه نمی شود زیرا ممکن است منجر به سردرگمی شود و درک و نگهداری کد را دشوار کند.

  • آیا می توانم مقادیر float را به متغیرهای نوع داده int در C اختصاص دهم؟

    بله، می توانید مقادیر float را به متغیرهای نوع داده int در C اختصاص دهید. با این حال، مقدار float به طور ضمنی به یک عدد صحیح تبدیل می شود. قسمت اعشاری مقدار شناور کوتاه می شود، به این معنی که به نزدیکترین عدد صحیح به پایین گرد می شود. به عنوان مثال، اگر مقدار float 3.9 را به یک متغیر int اختصاص دهید، مقدار ذخیره شده در متغیر 3 خواهد بود. اما انجام این کار توصیه نمی شود. برخی از کامپایلرها به شما هشدار می دهند.و باید آن را typecast کنید. همیشه توصیه می شود که یک مقدار نوع داده را به همان متغیر نوع داده اختصاص دهید.

داده ها در C


انواع داده ها در C :

انواع داده ها در C چیست؟

نوع داده نوعی داده است که به کامپایلر می گوید چه نوع داده ای قرار است در حافظه ذخیره شود. عمدتاً برای تعریف یک متغیر یا تابع در برنامه C استفاده می شود. نوع داده مشخصه ای است که به ماشین یا کامپیوتر یا میکروکنترلرها می گوید که چگونه مقدار را بخوانند و ذخیره کنند.

به بیان ساده تر، متغیر نام ناحیه ای از حافظه است. نوع داده، نوع داده ای است که باید در آن حافظه ذخیره شود.

int a = 15; :متغیری از نوع int ذخیره شده است.

char b = ‘g’; :متغیری از نوع کاراکتر ذخیره شده است.

float c = 9.7000000; :- متغیری از نوع فلوت ذخیره شده است.

double d= 6.800300000000; :-متغیری از نوع دابل ذخیره شده است.

کد زبر را اجرا نمایید :

				
					#include <stdio.h>

int main()
{
  int age = 15;
  printf ("%d",age);
  return 0;
}
				
			

در مثال بالا، سن (متغیر) نام حافظه است در واقع برچسبی که به محل ذخیره متغیر در حافظه اختصاص داده شده است. و int نوع داده است. یعنی در حافظه (متغیر age)، فقط اعداد صحیح را می توانیم ذخیره کنیم. همچنین در ادامه این آموزش خواهیم دید که چگونه مقادیر در حافظه ذخیره می شوند.

چرا از انواع داده در C استفاده می کنیم؟

انواع داده ها برای تعیین نوع داده هایی که قرار است در متغیرها نگهداری شوند استفاده می شود. هنگام ایجاد متغیر باید از انواع داده های مناسب استفاده کنیم. در ادامه این موضوع مهم رو به طور عمیق بررسی میکنیم.

انواع داده ها چیست ؟

انواع داده ها در C به سه دسته کلی تقسیم میشوند :

انواع داده ابتدایی یا پایه.

انواع داده های مشتق شده.

انواع داده های تعریف شده توسط کاربر.

خب بیاید با هم یکی یکی بررسیشون کنیم:

انواع داده های ابتدایی/پایه در C چیست؟

نوع داده پایه ابتدایی ترین نوع داده است که برای نمایش مقادیر ساده مانند عدد صحیح، کاراکتر، اعشاری، دوبل و void استفاده می شود.

 داده نوع int (Integer):

عدد صحیح یا int یک عدد کامل است که شامل اعداد مثبت و منفی است. این نوع داده شامل اعداد اعشاری و کسری نمی شود.

Valid int values: -10, 0, 10, 23, 35, 2023.

Invalid int values: -1.43, 1 3/4, 3.14, .09, 5,643.1

اندازه نوع داده int می تواند 4 بایت در ماشین های 32 بیتی و 64 بیتی و 2 بایت در ماشین های 16 بیتی باشد. مقدار حافظه اختصاصی کاملا وابسته به سیستم است.

مثال :

;int temp_variable = 100

int age = 9;

int number = -14;

داده نوع char (Character) :

از کلمه کلیدی char برای ایجاد متغیری استفاده می شود که بتوانیم کاراکترها را در آن ذخیره کنیم. اندازه نوع داده char  یک بایت است. بنابراین، می توانیم یک کاراکتر را در یک متغیر char ذخیره کنیم.

مثال :

char temp_char = 'T';

char initial = 's';

نوع داده float (Floating-Point) :

از آنجایی که int یا integer برای ذخیره اعداد کامل استفاده می شود، باید یک کلمه کلیدی جدید برای مقادیر اعشاری و کسری نیز داشته باشیم. نوع float یا شناور برای ایجاد فضای ذخیره سازی برای ذخیره مقادیر اعشاری استفاده می شود. اعداد اعشاری از دو قسمت تشکیل شده است، یک عدد کامل و یک جزء کسری. هر دو قسمت با یک نقطه اعشار از هم جدا می شوند.

به عنوان مثال، 16.56 یک عدد اعشاری است. در این عدد 16 جزء صحیح و 0.56 جزءاعشار است. به همین دلیل است که ما یک نوع داده جداگانه برای این نوع داده داریم. اندازه نوع داده شناور 4 بایت است. در این نوع داده float ، می توانیم 6 رقم اعشار را ذخیره کنیم.

به عنوان مثال :

float  temp_variable = 2.39; //2.390000

float temp = 13.2324; //13.232400

نوع داده double (Double Precision Floating-Point) :

این کلمه کلیدی نیز همان کلمه کلیدی float میباشد. تنها تفاوت این است که می توانیم 15 رقم اعشار را ذخیره کنیم. از آنجایی که تعداد اعشار افزایش یافته است، اندازه نوع داده Double نیز 8 بایت است.

نوع داده void :

این نوع داده خالی یک نوع داده ناقص است. در زبان انگلیسی void به معنی فاصله یا حاوی هیچ چیز است. اندازه نوع داده void صفر بایت است. در اکثر کامپایلرها، هیچ اندازه ای (بایت) برای نوع داده خالی اختصاص داده نشده است، اما در تعداد کمی از کامپایلرها مانند GCC، اندازه آن 1 بایت است.

معمولا متغیر را با استفاده از void تعریف نمی کنیم. از void بیشتر برای اشاره گرها ( void pointers ) استفاده می شود. و همچنین از آن در توابعی استفاده می‌کنیم که چیزی برمی‌گردانند و توابعی که هیچ آرگومان نمی‌گیرند.

				
					/* Function with no return and no argument */
void temp_function( void )
{
  /* code here dspworld.ir*/
}

/* void pointer */
void *ptr;
				
			

در جدول زیر میتوانید خلاصه انواع داده پایه را مشاهده نمایید :

تعیین کننده فرمت

سایز (Byte)

نوع داده

d-%i%

2 یا 4 بایت

int

c%

1 بایت

char

f%

4 بایت

float

lf%

8 بایت

double

-

0 یا 1 بایت

void


انواع داده های مشتق شده در برنامه نویسی C چیست؟ :

نوع داده‌های مشتق‌شده از انواع داده‌های اولیه یا پایه که در بالا بحث کردیم، مشتق شده‌اند. انواع داده های مشتق شده عبارت اند از :

Arrays

Functions

Pointers

در آموزشهای بعدی در مورد انواع داده مشتق شده صحبت خواهیم کرد.

انواع داده های تعریف شده توسط کاربر چیست؟

این ها انواع داده هایی هستند که توسط خود کاربر با ترکیب انواع داده های اولیه/پایه و انواع داده های مشتق شده تعریف می شوند. کاربر برای سفارشی کردن یا ایجاد انواع داده های جدید بر اساس نیاز خود در برنامه آزاد است.

Structures

Unions

Enums

ساختار یا structure  چیست؟

ساختار مجموعه ای از متغیرها از نوع داده های مشابه یا متفاوت است. بنابراین، ما می توانیم بسته ای از انواع داده های مختلف را در تحت عنوان یک نوع جدید داده ایجاد کنیم.

به عنوان مثال میخواهیم نوع جدیدی از داده را تعریف کنیم که در آن بتوانیم سوابق یک دانش آموز مانند نام،شماره دانش آموزی،نمره و موارد دیگر را ذخیره کنیم.برای این منظور از نوع داده ساختار استفاده میکنیم.

				
					struct student
{
  char name[20];
  int id;
  int roll_no;
  float marks;
};
				
			

در آموزشهای بعدی به طور عمیق تر در مورد ساختارها بحث خواهیم کرد.

نوع شمارشی چیست؟

enum نوع خاصی است که نشان دهنده گروهی از ثابت ها (مقادیر غیرقابل تغییر) است.

برای ایجاد enum از کلمه کلیدی enum و به دنبال آن نام enum استفاده کنید و موارد enum را با کاما جدا کنید.

				
					enum cars
{
  Bmw=0,
  Ferrari=2,
  Jeep=3,
  Mercedes-Benz=5
};
				
			


اصلاح کننده های نوع داده :

تغییر دهنده نوع داده یکی از کلیدواژه های زبان C است که برای اصلاح موارد زیر از انواع داده های اولیه یا ابتدایی استفاده می شود.

      • محدوده انواع داده ها.
      • اندازه فضای حافظه اختصاص داده شده به متغیر.

در زبان C، اصلاح کننده های نوع داده زیر موجود است.

اصلاح کننده های نوع داده در C :

      • short
      • long
      • signed
      • unsigned

برای تغییر اندازه متغیرها از اصلاح کننده های نوع داده کوتاه و بلند استفاده می شود. Short برای کاهش اندازه حافظه متغیر و long برای افزایش حافظه متغیر استفاده می شود.

برای تغییر علامت (مثبت یا منفی) متغیرها از کلیدواژه های signed و unsignedاستفاده می شود. اگر از کلمه کلیدی signed استفاده کنیم، آن متغیر می تواند اعداد مثبت (+ve) و منفی (-ve) را در خود جای دهد. اگر از کلمه کلیدی unsigned  استفاده کنیم، متغیر فقط می تواند اعداد مثبت (+ve) را نگه دارد.

توجه: اگر قبل از نوع داده از کلمه کلیدی signed یا unsigned استفاده نکنیم، کامپایلر به طور پیش‌فرض از اصلاح‌کننده نوع داده signed در طول کامپایل استفاده می‌کند.

				
					struct student
{
  char name[20];
  int id;
  int roll_no;
  float marks;
};
				
			

ما می توانیم این اصلاح کننده های نوع داده را قبل از انواع داده ها اضافه کنیم. و همچنین ما می توانیم اصلاح کننده ها را ترکیب کنیم.

در زیر مثالهایی از ترکیب انواع اصلاح کننده که با یکدیگر ترکیب شده اند آورده شده است .

signed int

signed char

unsigned int

unsigned char

signed short int

signed long int

signed long long int

unsigned short int

unsigned long int

unsigned long long int

long double


چگونه محدوده متغیر را پیدا می کنیم؟:

این بخش رو با یک مثال توضیح میدم.

کاراکتر بدون علامت را در نظر بگیریم که 8 بیت نیاز دارد. اگر همه بیت ها را با 0 پر کنیم، مقدار آن حداقل است.و اگر همه بیت ها را تا 1 پر کنیم، مقدار حداکثر آن حداکثر میشود.

حداقل مقدار کاراکتر بدون علامت (8 بیت) :

Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6  Bit 7 (MSB)
0 0 0 0 0 0 0 0

مقدار 8 بیت فوق 0 است. پس حداقل مقدار 0

حداکثر مقدار کاراکتر بدون علامت (8 بیت) است.

حداقل مقدار کاراکتر بدون علامت (8 بیت) :

Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6  Bit 7 (MSB)
1 1 1 1 1 1 1 1

مقدار 8 بیتی بالا 255 است. بنابراین، حداکثر مقدار کاراکتر بدون علامت 255 است.به ساده گی می توانیم از فرمول زیر برای محاسبه حداکثر مقدار استفاده کنیم.

				
					maximum value = ( 2^available bits to store the data ) - 1


				
			

برای کاراکتر بدون علامت، فرمول به صورت زیر خواهد بود،

				
					maximum value = 2^8 – 1 = 255.


				
			

در مورد کاراکتر علامت دار به چه صورت خواهد بود؟ از آنجایی که بیت 7 (MSB) برای ذخیره علامت استفاده خواهد شد، تنها 7 بیت (بیت 0 تا بیت 6) برای ذخیره داده ها دارد. حداکثر مقدار = 2^7 – 1 = 127. بنابراین، می‌توانیم داده‌هایی را ذخیره کنیم که از 127- تا 127+ است. به این ترتیب، ما می توانیم انواع داده های دیگر را محاسبه کنیم.

از کد زیر میتوانید برای دیدن سایز انواع داده ها استفاده نمایید.

				
					#include <stdio.h>  

void main() 
{
  printf("sizeof char is: %d bytes \n", sizeof(char));
  printf("sizeof unsigned char is: %d bytes \n", sizeof(unsigned char));
  printf("sizeof int is: %d bytes \n", sizeof(int));
  printf("sizeof unsigned int is: %d bytes \n", sizeof(unsigned int));
  printf("sizeof short int is: %d bytes \n", sizeof(short int));
  printf("sizeof unsigned short int is: %d bytes \n", sizeof(unsigned short int));
  printf("sizeof float is: %d bytes \n", sizeof(float));
  printf("sizeof double is: %d bytes \n", sizeof(double));
  printf("sizeof void is: %d bytes \n", sizeof(void));
  printf("sizeof long is: %d bytes \n", sizeof(long));
  printf("sizeof unsigned long is: %d bytes \n", sizeof(unsigned long));
  printf("sizeof long double is: %d bytes \n", sizeof(long double));
  printf("sizeof long long is: %d bytes \n", sizeof(long long));
  printf("sizeof long int is: %d bytes \n", sizeof(long int));
  printf("sizeof long long int is: %d bytes \n", sizeof(long long int));
}
				
			

خروجی برنامه بالا به صورت زیر میباشد.

				
					sizeof char is: 1 bytes 
sizeof unsigned char is: 1 bytes 
sizeof int is: 4 bytes 
sizeof unsigned int is: 4 bytes 
sizeof short int is: 2 bytes 
sizeof unsigned short int is: 2 bytes 
sizeof float is: 4 bytes 
sizeof double is: 8 bytes 
sizeof void is: 1 bytes 
sizeof long is: 8 bytes 
sizeof unsigned long is: 8 bytes 
sizeof long double is: 16 bytes 
sizeof long long is: 8 bytes 
sizeof long int is: 8 bytes 
sizeof long long int is: 8 bytes 
				
			

امیدوارم انواع داده ها را به خوبی درک کرده باشید. حال می خواهیم ببینیم که چگونه مقادیر توسط متغییرها در حافظه با انواع داده های مختلف ذخیره می شوند.


چگونه داده ها در حافظه ذخیره می شوند؟:

ابتدا ببینیم که مقادیر بدون علامت چگونه در حافظه ذخیره می شوند.

مقادیر بدون علامت :

برای این مثال، char بدون علامت که اندازه آن 8 بیت است را در نظر می گیریم. این مثال بسیار ساده و سرراست میباشد.

unsigned char a = 'S';

مقدار اسکی “S”  برابر با 0x53 است. بنابراین، داده ها مانند زیر ذخیره می شوند.

حداقل مقدار کاراکتر بدون علامت (8 بیت) :

Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6  Bit 7 (MSB)
1 1 0 0 1 0 1 0

به این ترتیب، تمام مقادیر بدون علامت مانند، int بدون علامت، مقادیر long بدون علامت نیز به همین ترتیب ذخیره میشوند.

مقادیر علامت دار:

برای این سناریو نیز char علامت دار (unsigned char) را در نظر خواهیم گرفت که اندازه آن 8 بیت خواهد بود. MSB برای ذخیره علامت و 7 بیت باقی مانده برای ذخیره داده ها استفاده می شود. بنابراین، می توانیم اعداد مثبت و منفی را از 127- تا 127 ذخیره کنیم.

اعداد مثبت مستقیماً در حافظه نمایش داده می شوند در حالی که اعداد منفی به صورت مکمل 2 نشان داده می شوند.

مثال زیر را در نظر بگیرید.

unsigned char a = -21;

از آنجایی که مقدار فوق یک عدد منفی است، به صورت مکمل 2 در حافظه ذخیره میگردد.

				
					 21     = 0001 0101
~21     = 1110 1010
~21 + 1 = 1110 1011
-21     = 1110 1011
				
			

حداقل مقدار کاراکتر بدون علامت (8 بیت) :

Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6  Bit 7 (MSB)
1 1 0 1 0 1 1 1

مقدار 21- مانند بالا در حافظه ذخیره می شود. به این ترتیب مقادیر علامت دار شده را میتوان در حافظه ذخیره نمود.

مقادیر float  و double :

عدد ممیز شناور مستقیماً در حافظه ذخیره نمی شود. بنابراین باید اعداد ممیز شناور به شکل استاندارد تبدیل شوند و سپس آن اعداد باینری تبدیل شده در حافظه ذخیره می شوند. نمایش نقطه شناور ممکن است از ماشینی به ماشین دیگر متفاوت باشد. در این آموزش به یکی از روش های استاندارد به نام نمایش عدد ممیز شناور IEEE 754 می پردازیم.


نمایش استاندارد IEEE 754:

طبق تعریف ویکی پدیا، استاندارد IEEE برای محاسبات ممیز شناور (IEEE 754) یک استاندارد فنی برای محاسبات ممیز شناور است که در سال 1985 توسط موسسه مهندسین برق و الکترونیک (IEEE) ایجاد شد. این استاندارد بسیاری از مشکلات موجود در پیاده‌سازی‌های ممیز شناور مختلف را برطرف می‌کند که استفاده قابل اعتماد و قابل حمل از آنها را دشوار می‌کرد. بسیاری از واحدهای ممیز شناور سخت افزاری از استاندارد IEEE 754 استفاده می کنند. این فرمت IEEE 754 دارای سه جزء است.

      • قسمت علامت
      • قسمت نما
      • قسمت مانتیس

قسمت علامت 1 بیت را اشغال می کند که برای تشخیص عدد مثبت (+ve) یا منفی (-ve) استفاده می شود.

اندازه شناور 4 بایت و دوبل 8 بایت است. به دو فرمت طبقه بندی می شود.

انواع داده float به صورت single precision که 32 بیت فضا اشغال میکند.

نوع داده float  به صورت double precision  که 64 بیت فضا در حافظه اشغال میکند.


سوالات متداول :

  • انواع داده ها در C:

    انواع داده در زبان C به انواع مختلفی از داده ها اشاره دارد که می توان از آنها برای ذخیره و دستکاری اطلاعات در زبان برنامه نویسی استفاده کرد. در C، انواع داده ها شامل اعداد صحیح، اعداد ممیز شناور، کاراکترها و اشاره گرها و غیره است. این نوع داده ها اندازه و قالب داده ها و همچنین عملیاتی را که می توان بر روی آنها انجام داد را تعیین می کند. درک انواع داده ها برای نوشتن برنامه های C موثر و کارآمد ضروری است.

  • انواع داده ها در C چیست؟

    سه نوع نوع داده در زبان برنامه نویسی C وجود دارد:

    1-انواع داده های اولیه/ پایه
    2-انواع داده های مشتق شده
    3-انواع داده های تعریف شده توسط کاربر

  • انواع داده های اولیه یا اولیه در C چیست؟

    این نوع داده ابتدایی ترین نوع داده است که برای نمایش مقادیر ساده مانند عدد صحیح، کاراکتر، شناور، دوبل و void استفاده می شود.

  • انواع داده های مشتق شده در C چیست؟

    این نوع داده های مشتق شده از انواع داده های اولیه یا پایه مشتق شده اند. انواع داده های مشتق شده هستند

    آرایه ها
    توابع
    اشاره گرها

  • انواع داده های تعریف شده توسط کاربر در C چیست؟

    این ها انواع داده هایی هستند که توسط خود کاربر با ترکیب انواع داده های اولیه/پایه و انواع داده های مشتق شده تعریف می شوند. کاربر برای سفارشی کردن یا ایجاد انواع داده های جدید بر اساس نیاز خو د میتواند از این نوع از داده ها استفاده کند.
    Structures-
    Unions-
    Enums

  • اصلاح کننده های نوع در C چیست؟

    اصلاح کننده نوع داده در C کلمات کلیدی هستند که می توانند برای تغییر رفتار یک نوع داده استفاده شوند. آنها می توانند محدوده مقادیری را که یک متغیر از یک نوع داده خاص می تواند نگه دارد تغییر دهند یا بر تخصیص حافظه برای آن متغیر تأثیر بگذارند. نمونه‌هایی از اصلاح‌کننده‌های نوع در C عبارتند از: "signed"، "unsigned"، "short" و "long".

در قسمت بعدی آموزش زبان برنامه نویسی C به بررسی متغیرها در زبان برنامه نویسی C خواهیم پرداخت.

پیج مارو در شبکه اجتماعی اینستاگرام دنبال نمایید.

عملگرهای بیتی در C


عملگرهای بیتی در C :

در آخرین آموزش ما در مورد عملگرها در برنامه نویسی C بحث کردیم. در قسمت قبل، فقط عملگرهای بیتی را بررسی نکردیم. بنابراین در این قسمت از آموزش قصد داریم در مورد عملگرهای بیتی در C صحبت کنیم.

 عملگرهای بیتی در C موضوع مهم برای مصاحبه و استخدام در حوزه سیستمهای تعبیه شده است. عنوان این قسمت از آموزش را دستکاری بیتها در C نیز میتوانیم نامگذاری کنیم.

عملگرهای بیتی در برنامه نویسی C

عملگرهای بیتی در C برای دستکاری ارقام دودویی مقادیر صحیح در سطح پایه ای مورد استفاده قرار میگیرند. این عملگرها کنترل دقیقی بر ساختار باینری اعداد صحیح، یافتن کاربردهای مشترک در وظایف برنامه نویسی سطح پایین، تعامل سخت افزاری و بهینه سازی الگوریتم های خاص را امکان پذیر می کنند.

عملگر

کاربرد عملگر

&

AND بیتی

|

OR بیتی

^

XOR بیتی

~

مکمل بیتی

شیفت به چپ

>>

شیفت به راست

<<

در آخرین آموزش ما در مورد عملگرها در برنامه نویسی C بحث کردیم. در قسمت قبل، فقط عملگرهای بیتی را بررسی نکردیم. بنابراین در این قسمت از آموزش قصد داریم در مورد عملگرهای بیتی در C صحبت کنیم.

 عملگرهای بیتی در C موضوع مهم برای مصاحبه و استخدام در حوزه سیستمهای تعبیه شده است. عنوان این قسمت از آموزش را دستکاری بیتها در C نیز میتوانیم نامگذاری کنیم.

عملگر بیتی AND (&) :

خروجی بیتی AND یک است اگر بیت های متناظر هر دو عملوند 1 باشند. اگر هر یک از بیت های یک عملوند 0 باشد، نتیجه بیت مربوطه 0 ارزیابی می شود.

برای بهتر فهمیدن موضوع بیاید با هم یک مثال رو بررسی کنیم، عملیات بیتی AND دو عدد صحیح 36 و 13.

عملگرهای بیتی در برنامه نویسی C

عملگرهای بیتی در C برای دستکاری ارقام دودویی مقادیر صحیح در سطح پایه ای مورد استفاده قرار میگیرند. این عملگرها کنترل دقیقی بر ساختار باینری اعداد صحیح، یافتن کاربردهای مشترک در وظایف برنامه نویسی سطح پایین، تعامل سخت افزاری و بهینه سازی الگوریتم های خاص را امکان پذیر می کنند.

				
					36 = 00100100 (In Binary)
13 = 00001101  (In Binary)

Bit Operation of 36 and 13

00100100
00001101                          (&)
________________
00000100 = 4 (In decimal)
				
			

عملکر بیتی OR (|) :

خروجی OR بیتی 1 است اگر حداقل یک بیت متناظر از دو عملوند 1 باشد. در برنامه نویسی C، عملگر OR بیتی با | نشان داده می شود.

مثال زیر رو با دقت بررسی کنید، عملیات بیتی OR دو عدد صحیح 36 و 13.

				
					36 = 00100100 (In Binary)
13 = 00001101  (In Binary)

Bit Operation of 36 and 13

00100100
00001101                          (|)
________________
00101101 = 45 (In decimal)
				
			

اپراتور  بیتی XOR (OR انحصاری) (^):

نتیجه عملگر XOR بیتی 1 است اگر بیت های متناظر دو عملوند مخالف هم باشند. با ^ نشان داده می شود.

				
					36 = 00100100 (In Binary)
13 = 00001101  (In Binary)

Bit Operation of 36 and 13

00100100
00001101                          (^)
________________
00101001 = 41 (In decimal)
				
			

عملگر مکمل بیتی (~) :

عملگر متمم بیتی یک عملگر یوناری یا یگانه میباشد. (فقط روی یک عملوند کار می کند). 1 را به 0 و 0 را به 1 تغییر می دهد. و با ~ نشان داده می شود.

عملگر شیفت به راست :

عملگر Right Shift همه بیت ها را با تعداد معینی از بیت های مشخص شده به سمت راست تغییر می دهد.و با  <<  نشان داده می شود.

				
					212 = 11010100 (In binary)
212>>2 = 00110101 (In binary) [Right shift by two bits]
212>>7 = 00000001 (In binary)
212>>8 = 00000000
212>>0 = 11010100 (No Shift)
				
			

عملگر شیفت به چپ :

عملگر شیفت به چپ همه بیت ها را با تعداد معینی از بیت های مشخص شده به سمت چپ تغییر می دهد. با >> نشان داده می شود.

				
					212 = 11010100 (In binary)
212<<1 = 110101000 (In binary) [Left shift by one bit]
212<<0 =11010100 (Shift by 0)
212<<4 = 110101000000 (In binary) =3392(In decimal)
				
			

همه آن چیزی که مربوط به عملگر بیتی است رو در چند خط بالا با هم بررسی کردیم.همین چند خط ساده در برنامه نویسی میکروکنترلر یا DSP و یا هر پردازنده دیگه ای بسیار بسیار کاربردی میباشد. و اگه برای مصاحبه به شرکتهای معتبر برید حتی ممکنه سوالاتی هم ازتون بپرسن.

تو ادامه با هم چندتا از سوالاتی که ممکنه ازتون پرسیده بشه رو باهم بررسی میکنیم.

ممنون که با ما همراهید.


عملگرهای بیتی در C - سوالات مصاحبه :

چگونه یک بیت خاص را در یک متغیر یا رجیستر تنظیم کنیم ؟

برای ست کردن هر بیت در یک متغیر، از عملگر OR استفاده کنید.

				
					Variable = Variable | (1<<x)   (or)   Variable |= (1<<x)


				
			

در اینجا “x” موقعیت بیت را نشان می دهد.

مثال: بیت چهارم را در ثبات A تنظیم کنید.

				
					A = A | (1<<4)  (or)  A |= (1<<4) 


				
			

چگونه یک بیت خاص را در یک عدد پاک کنیم؟

برای پاک کردن هر بیت در یک متغیر، از عملگرهای (AND ) و (مکمل(~)) استفاده کنید.

				
					Variable = Variable & ~(1<<x)    (or)    Variable &= ~(1<<x)


				
			

“x” موقعیت بیت را نشان می دهد

مثال: بیت پنجم را در ثبات B پاک کنید.

				
					B = B & ~(1<<5)     (or)      B &= ~(1<<5) 


				
			

چگونه می توان یک بیت خاص را در یک عدد تغییر داد یا ورق زد؟

برای جابجایی هر بیت در یک متغیر، از عملگر OR انحصاری (^) استفاده کنید.

				
					Variable = Variable ^ (1<<x)    (or)     Variable ^= (1<<x)   


				
			

“x” موقعیت بیت را نشان می دهد

مثال: بیت دوم را در ثبات B داده شده تغییر دهید.

				
					B = B ^ (1<<2)       (or)        B ^= (1<<2)


				
			

یک محدوده معین از بیت ها را تغییر دهید
به عنوان مثال، عدد 245 را در نظر بگیرید. فرمت باینری معادل 1111101 و  میخواهیم بیت 4 تا 7 رو صفر کنیم که این کار عدد 245 رو به  00000101 تبدیل میکند و معادل 5 در سیستم اعداد دهدهی میشود است.

				
					unsigned int rangeToggle(unsigned int num, unsigned int i , unsigned int j)
{
  return num ^ ((1<<(j-i)+1)-1)<<i;
}
				
			

چگونه بررسی کنیم بیت خاص در یک عدد تنظیم شده است یا نه؟

برای بررسی هر بیت در یک متغیر، از عملگر (&)  استفاده میکنیم.

				
					Variable & (1<<x)
				
			

x” موقعیت بیت را نشان می دهد.

مثال: بررسی کنید که آیا بیت 3 تنظیم شده است یا خیر.

				
					if((variable & (1<<3)) == 0) 
{
    printf("bit is not set");
} 
else 
{
    printf("bit is set");
}
				
			

استفاده از ماکرو برای پیاده سازی عبارات بیتی :

ما میتوانیم با استفاده از ماکروها در زبان برنامه نویسی C عبارات بالا را تعریف و مکررا در کد خودمون استفاده کنیم.مثالهایی که در ادامه مینوسیم رو حتما در کتابخانه های پردازنده ها دیده اید یا خواهید دید.

				
					#define SET_BIT(Variable, bit_position)    Variable |= (1<< bit_position) 
#define CLEAR_BIT(Variable, bit_position)    Variable &= ~(1<< bit_position) 
#define TOGGLE_BIT(Variable, bit_position)    Variable ^= (1<< bit_position) 
#define CHECK_BIT_IS_SET_OR_NOT(Variable, bit_position)    Variable & (1<< bit_position)
				
			

برای تعویض بایت ها در متغیر عدد صحیح 16 بیتی،یک MACRO تعریف کنید.

				
					#define ByteSwap16(Value) ((Value & 0x00FF) << 8) | ((Value & 0xFF00) >> 8)
				
			

برای تعویض بایت ها در یک متغیر عدد صحیح 32 بیتی،یک MACRO تعریف کنید.

				
					#define ByteSwap32(Value) ((Value & 0x000000FF) << 24) |
                                  ((Value & 0x0000FF00U) <<  8) |
                                  ((Value & 0x00FF0000U) >>  8) |
                                  ((Value & 0xFF000000U) >> 24)
				
			

برای تعویض بایت ها در یک متغیر عدد صحیح 64 بیتی، یک MACRO بنویسید.

				
					#define ByteSwap64(Value)   ((Value & 0x00000000000000FFU) << 56) | 
                                ((Value & 0x000000000000FF00U) << 40) | 
                                ((Value & 0x0000000000FF0000U) << 24) | 
                                ((Value & 0x00000000FF000000U) <<  8) | 
                                ((Value & 0x000000FF00000000U) >>  8) | 
                                ((Value & 0x0000FF0000000000U) >> 24) | 
                                ((Value & 0x00FF000000000000U) >> 40) | 
                                ((Value & 0xFF00000000000000U) >> 56)
				
			

فرد یا زوج بودن عدد را پیدا کنید.

				
					void odd_even( uint8_t  number )
{
  if( number & 1 )
  {
    printf(" Number is Odd\r\n");
  }
  else
  {
    printf(" Number is Even\r\n");
  }
}
				
			

اخرین بیت ست سمت راست را صفر کنید.

به عنوان مثال، عدد 144 را در نظر بگیرید. فرمت باینری معادل 10010000 است. بنابراین، خروجی باید 10000000 باشد که معادل 128 در سیستم دهدهی میباشد.

				
					uint8_t remove_last_set_bit( uint8_t  number )
{
    return (number & (number - 1));
}
				
			

بررسی کنید که آیا عدد توان 2 است یا خیر.

				
					void powerOf2( uint8_t  number ) 
{
  if(number & (number - 1))
  {
    printf("Number is not power Of 2");
  }
  else
  {
    printf("Number is power Of 2");
  }
}
				
			

تعداد بیت های ست را در یک عدد بشمارید

				
					unsigned int countSetBits( unsigned int number ) 
{
  unsigned int count = 0;
  while( number != 0)
  {
    count++;
    number &= (number-1);
  }

  return count;
}
				
			

دو بیت را در یک موقعیت معین در یک عدد صحیح عوض کنید.

				
					unsigned int swapBits( unsigned int number, unsigned int i, unsigned int j ) 
{
  number ^= (1 << i);
  number ^= (1 << j);
  
  return number;
}
				
			

همه بیت های زوج و فرد را عوض کنید.

به عنوان مثال، عدد 154 را در نظر بگیرید. فرمت باینری معادل 10011010 است. بنابراین، خروجی باید 01100101 باشد که معادل 101 در سیستم دهدهی میباشد.

				
					unsigned int swapOddEvenBits( unsigned int number ) 
{
  return ( ( number & 0xAAAAAAAA ) >> 1 ) | ( ( number & 0x55555555 ) << 1 );
}
				
			

امیدوارم از آموزشها تا اینجا لذت کافی برده باشد.

حتما خودتون هم مثالهارو تست و تمرین کنید تا دستتون راه بیوفته. تو آموزش بعدی انواع داده ها را در زبان برنامه نویسی C بررسی خواهید کرد.

حتما صفحه مارو در اینستاگرام دنبال کنید تا از انتشار قسمتهای جدید زودتر از بقیه مطلع بشید

 

عملگرها در زبان C


عملوند چیست؟

قبل از اینکه عملگرها را یاد بگیریم، باید بدانیم که عملوندها چه هستند.

عملوندها مقادیر یا متغیرهایی هستند که در برنامه نویسی کامپیوتری برای انجام عملیات استفاده می شوند. آنها می توانند اعداد، رشته ها یا انواع داده های دیگر باشند. به عنوان مثال، در “5 + 32” “5” و “32” عملوند هستند. به جای این اعداد می توانیم از متغیرها نیز استفاده کنیم.

اپراتورها در زبان C چه هستند؟

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

مثال :

							
					;sum = a + b 				
			

 در مثال بالا عبارات a و b عملوند و عبارت + از نوع عملگر یا اپراتور میباشد.

 


تقدم و همبستگی عملگرها چیست؟

تقدم عملگرها به ترتیبی که عملگرهای مختلف در یک عبارت ارزیابی می شوند اشاره دارد و توالی انجام عملیات را تعیین می کند. اپراتورهایی که اولویت بالاتری دارند قبل از آنهایی که اولویت کمتری دارند ارزیابی می شوند.

قوانین تقدم دقیق ممکن است بسته به زبان برنامه نویسی مورد استفاده متفاوت باشد. درک تقدم عملگرها برای اطمینان از ارزیابی صحیح عبارات مهم است.

ارتباط عملگرها به ترتیبی که عملگرهای دارای اولویت یکسان ارزیابی می شوند اشاره دارد. در زبان‌های برنامه‌نویسی، عملگرها می‌توانند همبستگی چپ یا راست ارتباطی باشند. عملگرهای ارتباطی چپ از چپ به راست ارزیابی می شوند، در حالی که عملگرهای ارتباطی راست از راست به چپ ارزیابی می شوند.

ارتباط یک عملگر تعیین می کند که چگونه عبارات حاوی چند عملگر ارزیابی شوند. درک ارتباط عملگرها برای نوشتن کد صحیح و کارآمد مهم است.

استفاده از اولویت و ارتباط عملگر :

تقدم  و انجمن دو موردی هستند که در عملگرها در شرایطی که برای ارزیابی ترتیب زمانی پرانتز وجود ندارند استفاده می شود.

در ریاضیات از قانون BODMAS پیروی می کنیم. به طور مشابه، در برنامه نویسی C نیز قانون تقدم عملگر و قانون انجمن اجرا میگردد.

 

							
					;int x = 4 + 3 * 2				
			

نتیجه عبارت بالا به جای 14 عدد 10 است. از آنجایی که عملگر * اولویت بیشتری نسبت به عملگر + دارد. بنابراین عملگر + بعد از عملگر * ارزیابی می شود.

در جدول زیر میتوانید نحوه محاسبه الویت عملگرها را مشاهده نمایید. این الویتها بسیار با اهمیت هستند و اگر هنگام کد نویسی به درستی مورد استفاده قرار نگیرند باعث خواهد شد عبارت نهایی با آنچه که انتظار داریم متفاوت باشد و کد ما دچار خطای منطقی شود.

الویت عملگر کارکرد وابستگی
1 () Parentheses Left to right
1 [] Array element reference Left to right
1 -> Member access via pointer Left to right
1 . Member access via object name Left to right
1 ++ Postfix increment Left to right
1 -- Postfix decrement Left to right
1 ! Logical NOT operator Left to right
1 ~ Bitwise complement operator Left to right
1 + Unary plus operator Left to right
2 Unary minus operator Right to left
2 ++ Prefix Increment Right to left
2 -- Prefix Decrement Right to left
2 * Indirection operator Right to left
2 ()sizeof Size of operator Right to left
2 (type) Typecast Right to left
3 *. Dereference operator Left to right
3 *<- Dereference operator Left to right
4 * Multiply Left to right
4 / Divide Left to right
4 % Modulus Left to right
5 + Binary addition Left to right
5 Binary subtraction Left to right
6 >> Bitwise left shift Left to right
6 << Bitwise right shift Left to right
7 > Less than Left to right
7 => Less than or equal to Left to right
7 < Greater than Left to right
7 =< Greater than or equal to Left to right
8 == Equal to Left to right
8 =! Not equal to Left to right
9 & Bitwise AND Left to right
10 ^ Bitwise XOR Left to right
11 | Bitwise OR Left to right
12 && Logical AND Left to right
13 || Logical OR Left to right
14 😕 Conditional operator Right to left
15 = Simple assignment Right to left
15 =* Assign product Right to left
15 =! Assign bitwise complement Right to left
15 =/ Assign quotient Right to left
15 =% Assign remainder Right to left
15 =+ Assign sum Right to left
15 =- Assign difference Right to left
15 =& Assign bitwise AND Right to left
15 =^ Assign bitwise XOR Right to left
15 =| Assign bitwise OR Right to left
15 =>> Assign bitwise left shift Right to left
15 =<< Assign bitwise right shift Right to left

توجه: عملگرهای ++/ -- بعد از متغیر دارای اولویت بالاتری نسبت به عملگرهای ++ / -- قبل از متغییر هستند.


انواع عملگرها در زبان C :

در زبان برنامه نویسی C  سه نوع عملگر داریم که این سه عملگر به هفت نوع عملگر فرعی تقسیم بندی شده است که در ادامه با آن ها آشنا می شویم.

 

اپراتور تکی :

اپراتوری است که برای کار/عمل کردن به یک عملوند نیاز دارد. سه نوع عملگر تکی موجود است.

عملگر افزایش (++)،

عملگر کاهش (–)،

 .sizeof() عملگر 

عملگرهای افزایش و کاهش را نمی توان در اعداد ثابت استفاده کرد. فقط با متغیرها استفاده می شود. پس بیایید جزئیات را یکی یکی ببینیم.

عملگر افزایشی (++) :

عملگر افزایشی برای افزایش یا اضافه کردن مقدار 1 استفاده می شود. دو نوع عمگر افزایشی وجود دارد.

پیش افزایشی و

پس افزایشی

عملگر پیش از افزایش (X++) :

وقتی از عملگر افزایشی قبل از عملوند استفاده می کنیم، پیش افزایش نامیده می شود. (یعنی ابتدا افزایش اتفاق می افتد و سپس مقدار به آن اختصاص می یابد). به عنوان مثال

 

				
					++x -> 1+x;
				
			

				
					int main()
{
    x = ++x //pre-increment
    //statements
}
				
			

مثال :

				
					#include <stdio.h>
int main()
{
    int x=5,y;
    y = ++x;
    printf("x = %d\ny = %d",y,x);
    return 0;
}
				
			

خروجی :

				
					x = 6
y = 6
				
			

توضیح کد: در این برنامه در داخل تابع main مقدار 5 را به متغیر 'x'  اختصاص داده ام، سپس مقدار 5 ابتدا با X++ افزایش می یابد که برابر با  1 + 5 = 6 است.  اکنون مقدار 6 به متغیر 'x' اختصاص داده می شود و نتیجه ذخیره شده در متغیر 'y' قرار میگیرد که آن هم برابر 6 میباشد.

عملگر پس افزایشی (++X) :

وقتی بعد از عملوند از عملگر افزایشی استفاده می کنیم، به آن پس افزایش می گویند. (یعنی ابتدا مقدار به آن اختصاص داده می شود و سپس افزایش اتفاق می افتد).

به عنوان مثال

				
					X++ -> 1+x;
				
			

				
					int main()
{
    x = x++; //post-increment
    //statements
}
				
			

مثال :

				
					#include <stdio.h>
int main()
{
    int x=5,y;
    y = x++;
    printf("x = %d\ny = %d",y,x);
    
    return 0;
}
				
			

خروجی :

				
					x=6
y=5

				
			

توضیح کد: در این برنامه در داخل یک main مقدار 5 را به متغیر 'x' که یک مقدار اصلی است، اختصاص داده ام، در ابتدا مقدار X برابر 5 میباشد و درون متغیر y قرار میگیرد و سپس مقدار متغیر x یک واحد اضافه میشد در دستور بعد که وظیفه چاپ مقادیر را دارد مقدار x برابر 6 و مقدار y برابر با 5 خواهد بود.

عملگر کاهش (X–) :

عملگر کاهش برای کاهش یا تفریق مقدار 1 استفاده می شود. دو نوع وجود دارد.

پیش کاهش

پس از کاهش

وقتی از عملگر کاهش قبل از عملوند استفاده می کنیم، به آن پیش کاهش می گویند. (یعنی ابتدا کاهش اتفاق می افتد و سپس مقدار به آن اختصاص می یابد).

به عنوان مثال :

				
					--x -> 1 - x ;
				
			

				
					int main()
{
    x = --x; //pre-decrement
    //statements
}
				
			

مثال :

				
					#include <stdio.h>
int main()
{
    int x=5,y;
    y = --x;
    printf("x = %d\ny = %d",y,x);
    
    return 0;
}
				
			

خروجی :

				
					x = 4
y = 4
				
			

نکته: - در این برنامه در داخل main مقدار 5 را به متغیر 'x' که یک مقدار اصلی است اختصاص داده ام سپس مقدار 5 ابتدا با x-- کاهش می یابد که نتیجه آن 4 = 1- 5 است. پس ابتدا مقدار x یک واحد کاهش میابد و برابر 4 میشود و سپس درون متغیر y قرار میگیرد.

اپراتور پس کاهشی (–X) :

وقتی بعد از عملوند از عملگر decrement استفاده می کنیم، به آن post-decrement می گویند. (یعنی ابتدا مقدار تخصیص داده می شود و سپس کاهش اتفاق می افتد). 

به عنوان مثال :

				
					--x -> x - 1 ;
				
			

				
					int main()
{
    x = x--; //pre-decrement
    //statements
}
				
			

مثال :

				
					#include <stdio.h>
int main()
{
    int x=5,y;
    y = x--;
    printf("x = %d\ny = %d",y,x);
    
    return 0;
}
				
			

خروجی :

				
					x = 5
y = 4
				
			

نکته: در این برنامه در داخل یک main مقدار 5 را به متغیر 'x' اختصاص داده ام که یک مقدار اصلی است ابتدا مقدار x که برابر 5 است به متغیر y اختصاص داده میشود و سپس یک واحد از آن کم میشود در نتیجه مقدار x برابر 1 می گردد.


اپراتور ()sizeof :

عملگر ()sizeof یک عملگر یگانه است که می تواند اندازه  عملوندش را برگرداند.  عمگر ()sizeof به شکل متفاوتی عمل میکند و مقدار حافظه اختصاص داده شده به عملوند یا متغییر ورودی خود را برمیگرداند.ورودی این عملگر نوع داده میباشد به عنوان مثال char, int,float  و غیره.

فرمت مشخص کننده ()sizeof  عبارت zu%  میباشد که در برنامه زیر ذکر شده است.

				
					sizeof(condition);
				
			

در اینجا، condition می تواند یک نوع داده یا یک متغیر از هر نوع باشد. 

مثال :

				
					#include <stdio.h>
int main()
{
    printf("sizeof char = %zu\n",sizeof(char));
    printf("sizeof int = %zu\n",sizeof(int));
    printf("sizeof float = %zu\n",sizeof(float));
    printf("sizeof double = %zu",sizeof(double));
}
				
			

خروجی:

				
					sizeof char = 1
sizeof int = 4
sizeof float = 4
sizeof double = 8
				
			

عملگر () sizeof یک اپراتور وابسته به معماری سیستم است که می تواند در یک کامپایلر سیستم 32 بیتی یا 64 بیتی اجرا شود و نتیجه های متفاوتی داشته باشد.مثلا در کامپایلر avr-gcc مقدار حافظه اختصاصی به نوع داده int دو بایت میباشد. پس همیشه معماری سیستمی که قراره کد روی آن اجرا بشه و فرضیات کامپایلر رو در نظر بگیرید وگرنه ممکنه دچار اورفلو بشید یا الکی حافظه رو هدر بدید!!!

				
					#include <stdio.h>
int main()
{
    int i=20;
    char c='C';
    double d=20.52;
    float f=3.4;
    
    printf("Maximum bytes = %d",sizeof(i + c + d + f));
}
				
			

خروجی:

				
					Maximum bytes = 8
				
			


اپراتورهای باینری :

عملگرهای باینری دسته ای از عملگرها در c  هستند که برای استفاده از آنها نیاز به حداقل  دو عملوند میباشد. برای مثال (10 + 5) در نظر بگیرید. در اینجا، ’10’ و ‘5’ عملوند هستند و ‘+’ یک عملگر است. عملگرهای باینری به پنج دسته تقسیم می شود.

  • Arithmetic Operator (+,-,*,/,%)
  • Assignment Operator(=,+=,-=,*=,/=,%=)
  • Logical Operator (&&,||,!)
  • Relational Operator(<,>,<=,>=,==,!=)
  • Bitwise Operator(&,|,^,~,<<,>>)

عملگر حسابی(+,-,*,/,%) :

عملگرهای حسابی عملگرهای ویژه در زبان C هستند. فقط برای عملیات ریاضی با حداقل دو عملوند استفاده می شود.

مثال :

				
					#include <stdio.h>
int main()
{
    int a = 4,  b = 2, c;
    
    c = a + b;
    printf("a + b = %d \n",c);
    c = a - b;
    printf("a - b = %d \n",c);
    c = a * b;
    printf("a * b = %d \n",c);
    c = a / b;
    printf("a / b = %d \n",c);
    c = a % b;
    printf("a % b = %d",c);
    
    return 0;
}
				
			

خروجی:

				
					a + b = 6 
a - b = 2 
a * b = 8 
a / b = 2 
a % b = 0
				
			

اپراتور تخصیص (=,+=,-=,*=,/=,%=):

عملگرهای تخصیص نیز عملگرهای ویژه ای در زبان برنامه نویسی C هستند. برای تخصیص مقدار به یک متغیر استفاده می شود. عملوند سمت چپ یک متغیر و عملوند سمت راست عملگر انتساب یک مقدار است.

مقدار سمت راست باید از نوع داده مشابه با متغیر سمت چپ باشد، در غیر این صورت، کامپایلر خطا خواهد کرد.

مثال :

				
					#include <stdio.h>
int main()
{
    int a = 5, b;
    
    b = a;      // b is 5
    printf("b = %d\n", b);
    b += a;     // b is 10 
    printf("b = %d\n", b);
    b -= a;     // b is 5
    printf("b = %d\n", b);
    b *= a;     // b is 25
    printf("b = %d\n", b);
    b /= a;     // b is 5
    printf("b = %d\n", b);
    b %= a;     // b = 0
    printf("b = %d\n", b);
    return 0;
}
				
			

خروجی:

				
					b = 5
b = 10
b = 5
b = 25
b = 5
b = 0
				
			

عملگر/عبارات منطقی (&&،||،!):

عملگرهای منطقی برای ترکیب دو یا چند شرط استفاده می شوند، بسته به درست یا نادرست بودن عبارت، 0 —> false یا 1 —> true را برمی گرداند. معمولاً در تصمیم گیری در برنامه نویسی C استفاده می شود.

 

 فرض کنید سه مقدار a = 50، b = 10، c دارید. سپس c = a > b را اجرا کنید که نتیجه آن درست است. بنابراین، 1 در c ذخیره می شود. و اگر b = 100 باشد آنگاه نادرست خواهد بود و c دارای مقدار 0 خواهد بود. بنابراین مفهوم در این عملگر منطقی می گوید که درست یا نادرست بودن آن به a > b بستگی دارد.

به همین ترتیب، در چنین مواقعی، شرایطی وجود خواهد داشت که شما بیش از یک شرط دارید و در آن زمان می توانید از یکی از عملگرهای  &&،|| استفاده نمایید.

انواع عملگر/بیان منطقی:

عملگر و منطقی

عملگر منطقی OR

عملگر منطقی NOT

اپراتور اتصال کوتاه

جدول درستی عملگر &&

عملگر Logical AND فقط در صورتی درست برمی گردد که همه شرایط درست باشند.

A&&B

B

A

FALSE

FALSE

TRUE

FALSE

TRUE

FALSE

FALSE

FALSE

FALSE

TRUE

TRUE

TRUE

جدول درستی عملگر ||

عملگر Logical OR فقط در صورتی درست برمی گردد که  حداقل یکی از شرایط درست باشد.

A||B

B

A

TRUE

FALSE

TRUE

TRUE

TRUE

FALSE

FALSE

FALSE

FALSE

TRUE

TRUE

TRUE

جدول درستی عملگر !

عملگر منطقی NOT فقط اگر شرط نادرست باشد، true را برمی گرداند.

B

A

FALSE

TRUE

TRUE

FALSE

مثالی از عملگر منطقی AND (&&).

				
					#include <stdio.h>
int main()
{
    int x = 20, y = 10, z = 15;
    if(x < y && y < z)
    
    {
        printf(" X is not greater number");
    }
    else
    {
        printf(" X is a greater number");

    }
    
    return 0;
}
				
			

خروجی:

				
					 X is a greater number

				
			

مثالی از عملگر منطقی OR (||):

				
					#include <stdio.h>
int main()
{
    int a = 20, b = 10, c = 15;
    if(c > a || c > b)
    
    {
        printf(" C is a greater number");        

    }
    else
    {
        printf("C is neither a smaller nor greater number");
    }
    
    return 0;
}
				
			

				
					 C is a greater number

				
			

مثالی از عملگر منطقی NOT (!):

				
					#include <stdio.h>
int main()
{
    int i = 20, j = 10;
    if(i != j )
    
    {
        printf("i is not equal to j");
    }
    else
    {
        printf("i is equal to j"); 
    }
    
    return 0;
}
				
			

خروجی :

				
					i is not equal to j

				
			

اپراتورهای اتصال کوتاه / عبارات (&&، ||) :

اتصال کوتاه روشی برای ارزیابی است که توسط کامپایلر برای بهینه سازی کد استفاده می شود. زیرا اجرا شدن برنامه در زمان کمتر و سرعت بیشتر گزینه مطلوب تری میباشد.، بنابراین برای کاهش پیچیدگی زمانی در یک برنامه برای ارزیابی عبارات شرطی کامپایلر از اتصال کوتاه (Short Circuit)   استفاده می کند. این عملگر اتصال کوتاه یا عبارت اتصال کوتاه در این مقاله، به عنوان عملگرهای اتصال کوتاه منطقی یا عبارت اتصال کوتاه منطقی نیز در زبان برنامه نویسی C شناخته می شود.

ارزیابی اتصال کوتاه برای AND منطقی (&&) :

اگر شرط اول نادرست باشد، کامپایلر شرط بعدی را اجرا نمی کند، فقط در شرایط اول یک اتصال کوتاه رخ خواهد داد.

مثالی از ارزیابی اتصال کوتاه برای AND منطقی (&&)

				
					#include <stdio.h>
int main()
{
    int a = 10, b = 5, c;
    
    c = ((++a > 15) && (++b > 2));
    printf("A = %d\nB = %d\nC = %d",a,b,c);
    
    return 0;
}
				
			

خروجی :

				
					A = 11
B = 5
C = 0

				
			

توجه: در اینجا من دو متغیر a = 10، b = 2 را در نظر گرفته ام و دو شرط را با اتصال کوتاه منطقی بررسی کردم c = (++a>15 && ++b>2)، بنابراین اکنون اگر شرط اول طبق عملگر اتصال کوتاه و منطقی نادرست شود، کامپایلر برای بررسی شرایط بعدی حرکت نمی‌کند، بلکه شرط دوم ممکن است درست یا نادرست باشد. بعد از اولین شرط به سادگی اتصال کوتاه اتفاق میوفتد و برنامه به خط بعد میرود.

ارزیابی اتصال کوتاه برای ORمنطقی (||) :

اگر شرط اول درست باشد، کامپایلر شرط بعدی را اجرا نخواهد کرد، فقط در شرایط اول یک اتصال کوتاه خواهد بود.

نمونه ای از ارزیابی اتصال کوتاه برای OR منطقی (||) :

				
					#include <stdio.h>
int main()
{
    int a = 10, b = 5, c;
    
    c = (++a > 5 || ++b > 10);
    printf("A = %d\nB = %d\nC = %d",a,b,c);
    
    return 0;
}
				
			

خروجی :

				
					A = 11
B = 6
C = 1
				
			

نکته: به همین ترتیب در اینجا نیز همان دو متغیر a = 10 و b = 2 را گرفته ام و دو شرط را با اتصال کوتاه منطقی بررسی میکنم c = (++a>5 || ++b>10) بنابراین اگر شرط اول مطابق با عملگر OR اتصال کوتاه منطقی درست شود، کامپایلر برای بررسی شرط بعدی نمی رود.

اما اگر چندین شرط وجود داشته باشد و از این رو، اگر شرط اول نادرست شود، کامپایلر برای بررسی شرط دیگر حرکت می کند تا زمانی که یک شرط درست باشد، اگر کامپایلر یک شرط درست را دریافت کند، به سادگی یک اتصال کوتاه خواهد داشت. ، و سایر شرط ها چک نخواهد شد.

اپراتور رابطه ای (<,>,<=,>=,==,!=) :

یک عملگر رابطه ای برای مقایسه مقادیر حسابی، منطقی و کاراکتری دو عملوند استفاده می شود. اگر شرط درست باشد، 1 را برمی گرداند. اگر رابطه نادرست باشد، 0 را برمی گرداند.

مثال :

				
					#include <stdio.h>
int main()
{
    int a = 5, b = 3;

    printf("%d == %d\t = %d\n", a, b, a == b);
    printf("%d > %d\t = %d\n", a, b, a > b);
    printf("%d < %d\t = %d\n", a, b, a < b);
    printf("%d != %d\t = %d\n", a, b, a != b);
    printf("%d >= %d\t = %d\n", a, b, a >= b);
    printf("%d <= %d\t = %d\n", a, b, a <= b);
    
    return 0;
}
				
			

خروجی :

				
					5 == 3	 = 0
5 > 3	 = 1
5 < 3	 = 0
5 != 3	 = 1
5 >= 3	 = 1
5 <= 3	 = 0
				
			

عملگر بیتی (&,|,^,~,<<,>>):

در آموزش بعدی به این عملگرهای Bitwise پرداخته ایم.

اپراتور سه تایی

عملگر سه تایی را عملگر شرطی نیز می نامند که با سه عملوند Expression1 Expression2 Expression3 یا مقدار واقعی یا مقدار نادرست کار می کند و به صورت ?: نشان داده می شود.

اپراتور مشروط

هر زمان که یک برنامه طبق یک دستور خاص به صورت شرطی اجرا شود، از عملگرهای شرطی استفاده می کنیم. اجازه بدین مثالی را مطرح کنیم. فرض کنید Expression1 شرطی است که باید ارزیابی شود. اگر شرط (Expression1) درست باشد، آن را اجرا می کند و نتیجه Expression2 را برمی گرداند، در غیر این صورت اگر شرط (Expression1) نادرست باشد، آن را اجرا کرده و نتیجه Expression3 را برمی گرداند.

مثال:

Condition ? True : False

max = num1 > num2 ? num1 : num2;

				
					#include <stdio.h>
int main()
{
    int num1,num2;
    printf("Enter two numbers:- ");
    scanf("%d %d",&num1,&num2);
    
    printf("The largest number is %d",(num1 > numm2 ? num1 : num2));
    return 0;
}
				
			

خروجی :

				
					Enter two numbers:- 8 9
The largest number is 9
				
			

ما همچنین اپراتورهای ویژه زیر را نیز در دسته عملگرها در زبان C داریم.

عملگر رشته سازی (#)
اپراتورهای چسباندن توکن (##)

که در قسمتهای آینده به انها خواهیم پرداخت.

 


سوالات متداول :

  • عملگرها درزبان C چه کاربردی دارند؟

    هر زمان که عملیاتی را روی داده ها انجام می دهید، باید از نمادهایی استفاده کنید که به عنوان عملگر شناخته می شوند. نماد در یک یا چند عملوند عمل می کند یا یک عملیات منطقی خاص را روی یک متغیر یا مقدار در زبان های C انجام می دهد، به عنوان مثال: (+، -، *، /، %). به داده هایی که برای کارکرد استفاده می کنیم عملوند می گویند.

  • اولویت و ارتباط عملگرها در C چیست؟

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

  • استفاده از اولویت و ارتباط اپراتور چه کاربردی دارد؟

    Precedence و Associativity دو موردی هستند که در عملگرها در شرایطی برای ارزیابی ترتیب شرط زمانی که پرانتز وجود ندارند استفاده می شود.

  • انواع اپراتورها چیست؟

    اپراتور یگانه یا تکی
    اپراتور باینری
    اپراتور سه تایی

  • چه زمانی می توانیم از عملگر pre-increment به جای عملگر post increment در C استفاده کنیم؟

    در C، عملگر pre-increment (++i) زمانی استفاده می شود که بخواهیم مقدار یک متغیر را قبل از استفاده در یک عبارت افزایش دهیم. از طرف دیگر، عملگر post-increment (i++) زمانی استفاده می شود که بخواهیم مقدار یک متغیر را پس از استفاده در یک عبارت افزایش دهیم.

  • اپراتورهای اتصال کوتاه در C چیست؟

    عملگرهای اتصال کوتاه در C فقط زمانی برای ارزیابی عملوند دوم استفاده می شوند که نتیجه عملوند اول برای تعیین نتیجه نهایی عبارت کافی نباشد. این بدان معنی است که اگر عملوند اول نتیجه عبارت را تعیین کند، عملوند دوم ارزیابی نمی شود و در نتیجه کارایی بهبود می یابد. دو عملگر اتصال کوتاه در C وجود دارد: عملگر AND منطقی (`&&`) و عملگر منطقی OR (`||`).

  • عملگر شرطی در C چیست؟

    عملگر شرطی در C یک عملگر سه تایی است که امکان ارزیابی شرطی عبارات را فراهم می کند. به سه عملوند نیاز دارد: یک شرط، یک نتیجه زمانی که شرط درست است، و یک نتیجه زمانی که شرط نادرست است. اگر شرط درست باشد، عبارت اول ارزیابی می شود. در غیر این صورت، عبارت دوم ارزیابی می شود. معمولاً به عنوان روشی کوتاه برای نوشتن عبارات ساده if-else در C استفاده می شود.