برای من فقط یک خط اضافه کرد تو کد ، در اینترنت سرچ کردم و دیدم برای بقیه هم مثل من بود و پروژه ها رو بدون مشکل انجام دادند. اما زمانی که کد همون جلسه رو استفاده میکردم در serial.manitor , همچین چیزی مینوشت : The function decode(&results)) is deprecated and may not work as expected! Just use decode() - without any parameter.
بدون استفاده از پارامتر هم از decode استفاده کردم و هر دکمه ای که فشار میدادم فقط 0 چاپ میکرد در مانیتور
استاد یه سوال هم راجع به & (results&)داشتم و متوجه نشدم که چه مکانیزمی دراه و چه تفاوتی با * داره، تا اون جایی که متوجه شدم این بود که آدرس اون متغیر رو ذخیره کرده ولی نفهمیدم که چرا ازش استفاده شد یا اینکه چرا از خود (*) استفاده نشد و مفهوم کلی و چرایی استفاده ازش رو درک نکردم . ممنون میشم راجع به این موضوع هم کمی توضیح بدهید .
سلام دوست عزیز، در مورد سوال اول: کلا کتابخانه هایی که در اینترنت وجود دارن، در گذر زمان، توسط تیم سازنده روشون کار میشه و بهبود داده میشن. این کتابخانه هم دچار همین موضوع شده و کمی تغییر کرده است. اینکه نوشته یک مورد deprecated شده یعنی اینکه دیگه نباید ازش استفاده کنید و داره منقضی میشه این طرز استفاده. در خیلی جاهای دیگه هم با لغت deprecated ممکنه مواجه بشید. داره میگه که دیگه لازم نیست به تابع decode چیزی پاس بدید و بدون پارامتر اون رو صدا بزنید. قبلا که decode رو صدا میزدیم، متغیر result رو هم بهش میدادیم که جواب رو داخل اون بریزه. الان احتمالا خودش جواب رو برمیگردونه و لازم نیست چیزی بهش پاس بدیم. پیشنهاد می کنم که صفحه github سازنده این کتابخانه سر بزنید تا آخرین توضیحات و آپدیت ها رو اونجا مطالعه کنید.
در مورد سوال دوم: بحث pointer ها در فصل های ابتدایی به صورت آشنایی برای شما آورده شده و در ادامه و مخصوصا در فصل arm به طور خیلی خیلی مفصل بهش میپردازیم و به کرات ازش استفاده می کنیم و اونجا کاملا جا میفته براتون. ولی من اینجا هم به صورت خلاصه یک توضیح میدم. وقتی که شما یک متغیر رو میسازید، مثلا متغیر myVariable از نوع byte و داخلش مقدار مثلا ۵ رو ذخیره می کنید، سیستم میاد و یک بایت از حافظه ram رو برمیداره و داخلش مقدار ۵ رو ذخیره می کنه. اینکه شما اسم این متغیر رو چی گذاشتید، اصلا و اصلا اهمیتی نداره برای سیستم و حتی خبر نداره از این اسم. این اسم فقط برای شماست که بتونید برنامه رو دنبال کنید و برای سیستم هیییچ معنی و مفهومی نداره. در عوض، آدرس خونه ای که این متغیر داخلش ذخیره شده برای سیستم مهم هست. اینکه این متغیر کجای حافظه هست و بعدا چطوری بهش دسترسی پیدا کنه که میشه آدرس اون متغیر. آدرس متغیر یک عدد هست که بسته به نوع معماری میکرو و حافظه هاش، توسط خود سیستم اختصاص داده میشه و شما نباید درگیر اون بشید. از نظر شما، اون متغیر myVariable هست و از نظر سیستم، اون متغیر، چیزی هست که داخل آدرس خاصی از حافظه قرار داره. (پس اینکه شما اسم متغیر هاتون رو کوتاه یا خیلی بلند انتخاب کنید، تاثیری در حجم برنامه شما نداره!) خب حالا فرضا شما می خواید این متغیر رو مقدارش رو استفاده کنید، چیکار می کنید؟ تو برنامه هرجا بنویسید myVariable، خود سیستم می فهمه که منظور شما مقداری هست که در فلان جای حافظه ذخیره شده و میره و مقدارش رو میاره. اما مسئله همیشه انقدر ساده نیست. فرض کنید که شما در یک متغیر به اسم myString، مقدار Hello My Name Is Mehrad رو ذخیره کردید. همونطور که توضیح دادیم (و در فصل های آینده هم بارها تکرار می کنیم تا کاملا جا بیفته)، مقدار این متغیر از نوع String هست. (یعنی رشته ای از کاراکترها) و این نوع متغیر در حافظه به صورت رشته ای از کاراکتر های ذخیره میشه. یعنی خود سیستم از یک جای حافظه شروع می کنه به ذخیره کردن و اول H و بعد e و بعد l و بعد l و بعد o و … به همین ترتیب همه این ها رو داخل ram می نویسه. حالا از کجا بدونه که چند تا بوده؟ بعدا چطوری بهش دسترسی پیدا کنه که با بقیه قاطی نشه؟ میاد آدرس خونه اول رو نگه میداره، و بعد از اینکه همه کاراکتر ها رو ذخیره کرد، در آخرش یک null (که همون 0 هست) رو اضافه میکنه. حالا هرموقع که شما مقدار این متغیر رو بخواید بخونید، فقط خونه اول رو که داشته باشید، می تونید کاراکترها رو دونه دونه بخونید تا به null برسید و سیستم می فهمه که به انتهای رشته رسیده. پس توی این مورد، وقتی که شما می نویسید myString، دیگه مثل اون متغیر قبلی نیست که راحت مقدار رو بهتون برگردونه، بلکه myString اشاره می کنه به خونه اولی که اون کاراکترها داخلش ذخیره شدن. همین اشاره کردن یعنی point کردن و بهش میگن pointer. بنابراین وقتی که بخواید این متغیر رو به جای دیگه پاسکاری کنید، به جای اینکه هر دفعه کل Hello My Name … رو دونه دونه برای اون تابع دیگه ارسال کنید، فقط آدرس خونه اول رو بهش میدید و اینطوری خیلی راحت اون متغیر پاس داده میشه و حجم اطلاعات ارسالی کم میشه و سیستم خیلی سریعتر کار می کنه. بنابراین ما دو مدل پاسکاری متغیر داریم. یکی بهش میگن by value یعنی مقدار اون پاس داده میشه. در این حالت، مقدار متغیر کپی میشه داخل یک متغیر دیگه و اون پاس داده میشه به تابع و اگر تابع مقدار اون رو عوض کنه، متغیر اصلی دست نخورده باقی میمونه. یک مدل دیگه بهش میگن by reference یعنی آدرس اون متغیر رو پاس میدیم و اینطوری اگر تابع به اون متغیر دست بزنه، متغیر اصلی هم تغییر میکنه. در آرایه ها و تابع ها و string ها، اسم متغیر، خود به خود یک pointer به خانه اول متغیر هست ولی در متغیر هایی مثل int برای اینکه آدرس رو پاس بدید، باید از علامت & قبل از اسم متغیر استفاده کنید. حالا داخل تابع، اگر بخواید به مقداری که داخل یک خونه از حافظه هست دسترسی پیدا کنید، باید یک * قبل از آدرس اون متغیر بذارید. امیدوارم این موضوع براتون جا افتاده باشه. باز هم هر قسمتی که براتون مبهم بود همینجا بپرسید.
سلامی دوباره ، استاد راجع به سوال دوم من تحقیق کردم و به یه سری نتایج رسیدم که شرح میدم که متوجه بشم درست متوجه شدم یا نه؟ به طور خلاصه اگه بخوام بگم ، در مبحث pionter ، از * زمانی استفاده میشود که قرار فانکشنی یا متودی یا … بره خونه اولش و یه چیزی رو بخونه که از قبل اونجا بوده و نمیتونه(نباید) تغییرش بده ،ولی & که آدرس اون متغیر رو داره مثلا (2603) ، برای اینه که فانکشن یا متود یا … بره خودش یه تغییری رو در اون آدرس انجام بده و قرار نیست چیزی بخونه .
ولی یه سوال که هنوز مبهم برام ، اینه که به جای & ، چرا خود متغیر رو پاس ندیم ، چرا آدرسش ؟ چه فرقی با هم دارند؟ مگه خود متغیر هم نمیشه مقدارش رو عوض کرد که باید آدرسش رو داد؟ با تشکر فراوان از راهنمایی هاتون استاد.