با سلام خدمت دوستان عزیزم توی این مبحث از آموزش آردوینو میخوام راجع به نکات ریزی که خیلی به چشم نمیاد و معمولا کسی بهش اهمیتی نمیده اما یادگیری و استفاده از اونا توی برنامه،برنامه را قابل فهم تر،آسون تر و سریعتر میکنه.
هر آنچه در تعریف متغیر باید بدانیم
از اونجایی که همتون با معرفی متغیر آشنایی دارید اینا رو دیگه توضیح نمیدم و میرم سره اصل مطلب :
اولین مبحثی که میخوام راجع بش صحبت کنم کلمه کلیدی unsigned :
همونطور که میدونید اگر این کلمه قبل از هر متغیری بیاد بازه اون متغیر اعداد مثبت میشه و دیگه اعداد منفی رو در نظر نمیگیره ( اگه قبل از نوع متغیر unsigned نزاریم بازه منفی هم خواهیم داشت).
حالا بریم چند تا مثال بزنیم که مفهومش قابل فهم تر بشه و نکات مهمشو بگم:
1 2 |
unsigned byte a = 10; byte b = -10; |
تا اینجای کار که روتین بود و مشکلی نداشتیم اما یه نگاهی هم به مثال پایین بندازید:
1 |
unsigned byte c = -10; |
در اینجا عدد 10 رو میاد از ماکزیمم عدد بسته به نوع متغیر کم میکنه یعنی توی این مثال 10-256 میشه و مقدار 246 در متغیر ذخیره میشه.
انواع کلاس برای تعریف متغیر :
در ابتدای کار باید بگم که متغیرها از نظر نوع ذخیره شدن به دو نوع global و local مورد استفاده قرار میگیرن که توی موارد پایین فرق اینا رو توضیح میدم.
1) auto : این نوع تعریف متغیر همون حاالتیه که هممون ازش استفاده میکنیم مثل چند تا مثال بالا.حالا این خودش 2 حالت ایجاد میشه وقتی که متغیر رو دقیقا در ابتدای برنامه و قبل از شروع تابع ها تعریف کنیم این میشه از نوع global و توی همه توابعمون میتونیم ازش استفاده کنیم و مقادیر محفوظ میمونه.
1 2 3 4 5 |
int a; void setup() { } void loop() { } |
حالا اگر ما این نوع تعریف رو توی تابع ها بکار ببریم از اون متغیر فقط توی همون تابع میتونیم استفاده کنیم.
1 2 3 |
void hasan() { int a = 0; } |
طبق مثال بالا چون متغیرمون رو از نوع محلی یا local تعریف کردیم متغیر با اتمام تابع از بین میره یعنی اگر ما توی این تابع 10 تا به مقدار متغیر اضافه کنیم با بیرون رفتن از این تابع و فراخوانی مجدد مقدار اون متغیر 10 نیس بلکه صفره!!! حالا برای رفع این مشکل باید چیکار کنیم؟ راه اول این که نوع متغیر رو به global تغییر بدیم یا از حالت دومی که پایین میگم استفاده کنیم.
حالا نکته ای که وجود داره :
1 2 3 4 5 6 7 8 9 10 |
int a = 10; void hasan() { int a = 0; int b = a + 2; } void setup() { } void loop() { hasan(); } |
خب حالا به نظرتون توی مثال بالا چه اتفاقی میوفته،کدوم a رو در نظر میگیره ؟؟؟ مقدار متغیر b چند میشه؟؟؟
باید خدمتتون بگم که در اینجا اون متغیری که توی همون تابع هست رو در نظر میگیره یعنی در اینجا مقدار b=2 میشه.
2) static : اگر از این نوع کلاس استفاده کنیم و متغیر توی تابع تعریف بشه،نوع متغیر از نوع local میشه ولی با اتمام تابع مقدار متغیر از بین نمیره یعنی اگر توی تابع 10 تا به متغیر اضافه بشه مثلا با 3 بار فراخوانی فانکشن مقدار متغیرمون 30 میشه بر خلاف مورد 1 که 100 بارم فراخوانی کنیم با هر بار اتمام مقدارش 10 هست.
1 2 3 4 |
void hasan() { static int a; a += 10; } |
حالت دوم استفاده از این کلاس تعریف به شکل زیر هست :
1 2 3 4 5 6 7 |
void hasan() { } static int a; void hasan1() { } void hasan2() { } |
توی مثال بالا متغیر a در دو تابع بعد از خودش قابل استفاده هست و توی تابع قبلیش یعنی hasan نمیتونیم ازش استفاده کنیم.
دو مورد کلاس تعریف متغیر دیگه هم هست به نام register و extern که اینجا خیلی بکار ما نمیان هر کسی خواست خودش میتونه راجع بش سرچ کنه.
خب بریم سراغ ساختمان ها :
1) struct : توی آرایه ها همونطور که میدونید همه اعضا از یک نوع هستن مثل [int a[10 که 10 تا عضوش از نوع عدد صحیح هست حالا ما اگر خواستیم اعضا از نوعهای مختلف باشن میتونیم از struct استفاده کنیم :
1 2 3 4 5 |
struct ABC { int a; char c; float d; }; |
که چون اندازه int دو بایت، اندازه char یک بایت و اندازه float چهار بایته در کل این ساختمان 7 بایت از حافظه رو اشغال میکنه.
حالا برای استفاده از این ساختمان باید یک شی از روش بدین صورت بسازیم:
; ABC aaa < == نام شی نام ساختمان
حالا برای مقدار دهی این شی به روش زیر عمل می کنیم:
1 2 3 |
aaa.a = 100; aaa.c = 'z'; aaa.d = 2.25; |
2) union : اینم مثل حالت بالاست با این تفاوت که فضای کمتری از حافظه رو اشغال میکنه(به اندازه بزرگترین نوع متغیر که چون اینجا بزرگترینش float بود 4 بایت اشغال میکنه بر خلاف حالت بالا که 7 بایت اشغال میکرد.)
1 2 3 4 5 |
union ABC { int a; char c; float d; }; |
نکته : در 2 حالت بالا حواستون به علامت ; در انتهای کروشه باشه.
3) enum : این نوع ساختمان بیشتر برای خوانایی برنامه استفاده میشه :
1 2 3 4 5 |
enum MONTH { farvardin, ordibehesht, khordad, }; |
برای استفاده باید یکی شی از روش بسازیم :
1 |
MONTH month1; |
حالا برای مقداردهیش از دستور زیر استفاده می کنیم :
1 |
month1 = farvardin; |
خب این کارا رو کردیم حالا چه اتفاقی قراره بیوفته؟؟؟
توی این ساختمانها توی حالت پبشفرض اولین اسم مقداره صفر میگیره و به مقدار اسمای بعدی یک واحد اضافه میشه یعنی توی مثال بالا farvardin=0،oridibehesht=1،khordad=2 هست.
البته خودمونم میتونیم مقداردهی کنیم :
1 2 3 4 5 |
enum MONTH { farvardin = 1, ordibehesht, khordad, }; |
در مثال بالا farvardin=1،oridibehesht=2،khordad=3 می شود.
یه نکته دیگه راجع به تعریف متغیر توی آردوینو بگم و بحث رو تموم کنم :
چند نوع دیگه متغیر توی آردوینو بکار میره که اینجا نام می برم:
uint8_t متغیر 8 بیتی با بازه مثبت
int8_t متغیر 8 بیتی با بازه مثبت و منفی
unit16_t متغیر 16 بیتی با بازه مثبت
int16_t متغیر 16 بیتی با بازه مثبت و منفی
مثال :
1 |
uint8_t ali = 0; |
آموزش جامع آردوینو جلسه ۱۲ Data Types And Conversion
مهمان
سلام
?
مهمان
سلام.ممنون از سایت خوبتون.موقع تقسیم یه عدد به عدد دیگه،اگر اعشارش خیلی طولانی بشه جواب صحیح نمیشه.مثلا جواب صحیح میشه ۲٫۶۶۶۶۶۶۶۶۶۶۶۶
ولی تو سریال ۲٫۶۷ یا ۲٫۶۶۶۷ نمایش میده.چیکار کنم تا از این امر جلوگیری بشه؟
مدیر سایت
سلام – رند میکنه دیگه – راهش رو من بلد نیستم والا.
حالا کارتو بگی بهتر میتونم راهنماییت کنم
مهمان
سلام خسته نباشید اگر برای شما اکان داره در مورد این لینک توضیح بفرمایید
https://forum.arduino.cc/index.php?topic=451441.0
مهمان
سلام خدا قوت پهلون
من معنی این کد رو متوجه نمیشم در نهایت خروجیش چیه؟
DDRA &= ~(1<<۰)
این تو پرانتز الان یک واحد شیفت داده یا پورت۰ رو ورودی کرده؟
و همینطور این
DDRA &= ~(1<<۲)
که الان ۲ رو شیفت داده و شده پایه ۳ و پایه ۳ رو نات کرده شده ۰ و ورودی شده؟
مدیر سایت
سلام
DDRA &= ~(1< <۰) >>>> بیت ۰ رجیستر DDRA رو ۰ کردیم.
DDRA &= ~(1< <۲) >>>> بیت ۲ رجیستر DDRA رو ۰ کردیم.
از منو C/++C سایت تو یه مطلبی تمام این موارد توضیح داده شده – ۰و۱ کردن بیت های رجیستر ها
مهمان
سلام خیلی عالی بود
درباره متغیر long ومشابه اون هم توضیح بدین .
ممنون
نویسنده این مطلب
long مثل بقیه متغیرهاست ولی ۳۲ بیتیه چیزه خاص دیگه ای نداره که
مهمان
سلام مهندس خسته نباشی و پیروز باشین….برای اشاره گر از این تابع به اون تابع هم یا یه تابع با چند خروجی مثالی برای اردوینو بزنیند خیلی متشکرم
مدیر سایت
سلام – مثال بگو چی بزنم تا کدش رو بنویسم.
نویسنده سایت
ممنون از توضیحات خوبت مسعود جان
مهمان
سلام مهندس خوبی انشالله؟
چجوری میکرو رو به اینترنت وصل کنیم؟
یعنی یه دستوری رو از اینترنت به میکرو بدیم مثلا بگیم Led رو روشن کن
نویسنده این مطلب
شما برای این کار باید از ماژول esp8266 استفاده کنید.
مدیر سایت
چند تا سوال
1) یه جای مطلب گفتی “مقادیر محفوظ میمونه“(سرچ کنی همینو پیدا میکنی) یعنی چی دقیقا؟ متغییر سراسری مقدار محفوظ میمونه؟؟؟!!!
2) یه جای دیگه گفتی “با بیرون رفتن از این تابع و فراخوانی مجدد مقدار اون متغیر 10 نیس بلکه صفره“(اینم سرچ کنی پیدا میکنی) مگه به متغیر های local در خارج از تابع تعریف شدشون میشه دسترسی پیدا کرد؟ خودت گفتی با خارح شدن از اون تابع(تابعیی که متغییر مد نظر توش تعریف شده) متغییر از بین میره، خب چطور میخوای بهش دسترسی پیدا کنی؟ که اومدی میگی در خارج از تابع مقدار متغیییر 0 هستش؟؟؟ من متوجه نمیشیم.
3) یه جای دیگ گفتی “کدوم a رو در نظر میگیره ؟؟؟” >> خب چیکار کنیم که متغییر سراسری a رو در نظر بگیره و نه اون a ایی که local هستش؟؟؟
4) تو یحث static ، خب از همون اول متغییر رو چرا سراسری تعریف چرا نمیکنیم؟ و از این کلمه کلیدی استفاده میکنیم؟
5) فرق دقیق بین union و struct چیه؟ من فرقشون رو متوجه نشدم ^_^
اینا چند تا سوال(که زیاد هم نیستش^_^) رو جواب بدی ممنون میشم.
نویسنده این مطلب
سوالایی خیلی خوبی پرسیدی
این مطلبو گفتم واسه وقتایی که برنامه زیاده و نگرانیم که نکنه حالا بین متغیرهای محلی و سراسری تشابه اسمی باشه با این شرایطی که گفتم دیگه جای نگرانی نیس.
.
1) محفوظ میمونه یعنی با اتمام تابع و فراخوانی مجدد مقدارش صفر نیس و بستگی به آخرین مقداردهی داره(حالا هرجای برنامه که میخواد باشه).
2) نگفتم از بیرون بهش دسترسی داریم گفتم با فراخوانی مجدد(یعنی یه بار تابع اجرا بشه تموم بشه بره بیرون و دوباره صداش بزنیم از اول شروع بشه).
3) خب یه اسم دیگه واسش میزاریم
4) چون با این کلمه متغیر از نوع محلی تعریف میشه و فضای کمنری رو اشغال میکنه میدونم که با بیرون رفتن از تابع از بین میره ولی حالا چطوری مقدارش محفوظ میمونه خدا میداند
5) این سوالت خیلی خوب بود.همونطور که گفتم union فضای کمتری اشغال میکنه خب حالا با این وضع پس دلیل وجود struct چیه؟؟؟شما فرض کن ما یه struct داریم یه union و هر کدومشون 2 تا عضو دارن یکی از نوع int یکی از نوع char;
توی struct ما میتونیم همزمان متغیر از هر دو نوع رو مقداردهی کنیم(هم از نوع int هم از نوع char) اما توی union در آن واحد فقط میتونیم یک نوع متغیر رو مقداردهی کنیم(یعنی توی این مثال یا فقط از نوع int باشه یا فقط از نوع char).
مهمان
خیلی ممنون اگه ممکنه در مورد برد کنترلر های اردینو مثل شیلد درایو سی انسی مطلب بگدارید
مدیر سایت
لینک زیر رو ببینید و بخونید و اونجا مطرح کنید درخواستتون رو.
چه مطلبی بزارم تو سایت؟