نمایش/عدم نمایش سایدبار
رفتن به بالای صفحه
مهدی دمیرچیلو

روش های ارسال متغییر به تابع در C

به نام خدا : تو این مطلب سومین قیمت از سری مطالب “آموزش زبان C” میخوام درباره روش های ارسال متغییر به تابع در C و ++C صحبت کنم، و این که چند مثال برنامه نویسی براتون بزنم، این که کی باید از کدوم روش استفاده کنیم، فرقشون چیه و چه مزایا و معایبی هر کدوم دارن و…
روش های ارسال متغییر به تابع در C

روش های ارسال متغییر به تابع در C

پیش نیاز این مطلب : آموزش جامع اشاره گرها در Pointer Tutorial in C
 
انواع روش ارسال داده به تابع :

  1. ارسال از طریق مقدار
  2. ارسال از طریق ارجاع
  3. ارسال از طریق ارجاع ثابت

خب برای این قسمت به کتاب دکتر فراهانی فصل ۵ مراجعه کنید(لینک دانلودش رو در مطلب قبلی این سری از مطالب گزاشتم)
این لینک هم بد نیست : Function | توابع در C++
 
ارجاع چیست : ارجاع یه کپی از یه متغییر هستش(یه نام مستعار هستش، حالا شاید کپی زیاد کلمه درستی نباشه، همون نام مستعار بهتره)، که آدرسش با متغییر اصلی یکسان است و مقدارش هم همین طور و هر تغییری در مقدار یکی از این دو باعث تغییر اون یکی میشه، لذا به همین دلیل هستش که میگن متغییر های از نوع ارجاع یه متغییر وابسته هستند و نه مستقل.
 
نحوه تعریف یه ارجاع : در زیر نحوه تعریف یه ارجاع رو میبینید، یه متغییر تعریف میکنیم(A) و بعد براش یه نام مستعار تعریف میکنیم(A2)

 
مطالعه بیشتر : بخش ۷٫۷ از فصل ۷ کتاب دکتر احمد فراهانی
 
کاربرد متغییر های (از نوع) ارجاع : کاربردش رو در عنوان بعدی(“روش های ارسال متغییر به تابع”) میبینید.
 
توجه : “ارجاع” برای زبان ++C هستش و در سی وجود نداره، در ادامه روش هایی رو میگیم؛ مثلا ارسال از طریق ارجاع و یا ارجاع ثابت، مدل مشابه ارجاع در C هم وجود داره که بابد از اشاره گر ها استفاده کنیم.
 

روش های ارسال متغییر به تابع

خب همون طور که میدونید بعضی وقتا باید یه سری متغییر رو به تابع ارسال کرد و یه چیزایی رو دریافت کرد؛ حالا این ارسال متغییر به تابع، روش های مختلفی براش وجود داره که در زیر میگم :
۱) ارسال از طریق مقدار (در هر دو زبان C و ++C وجود دارد)

  • در این روش مقدار متغییر ارسال میشه برای تابع.
  • تابع نمیتواند تغییری در متغییر اصلی ایجاد کند.
  • توابعی که فقط از این روش استفاده میکنن فقط میتونن یه متغییر ارسال کنن(به کمک دستور return)


مثال برنامه نویسی ۱
(“ارسال از طریق مقدار” در هر دو زبان C و ++C وجود داره و به همین صورت هستش.)
همون طور که در زیر میبینید یه تابع به نام Print تعریف کردم که یه پارامتر از نوع int داره، ما تو خط ۱۱ میایم مقدار متغییر Data رو ارسال میکنیم به تابع Print و و این مقدار در خط ۱۷ توسط تابع دریافت میشه و در متغییر MyData ذخیره میشه.

 
۲) ارسال از طریق ارجاع

  • در این روش آدرس متغییر ارسال میشه برای تابع.
  • تابع میتواند مقدار متغییر اصلی رو تغییر بده.(بعضا نیاز هستش که تابع متغییر اصلی رو تغییر بده و لذا باید از این روش ارسال استفاده کنیم)
  • این روش در جایی کاربرد داره که بخوایم چندیدن متغییر از تابع دریافت کنیم.(چون میایم آدرس چندین متغییر رو برای تابع ارسال میکنیم و تابع اون متغییر ها رو تغییر میده و دیتای لازم رو توشون ذخیره میکنه و انگار تابع برای ما دیتا ارسال کرده ^_^ )
  • از تعریف یه متغییر جدید خودداری میشه، مثلا فرض کنید میخواستیم یه آرایه با تعداد خونه ۱۰۰۰ تا به تابع ارسال کنیم، اگه میومدیم و از روش “ارسال از طریق مقدار” استفاده میکردیم، باید مقدار این آرایه ۱۰۰۰ خونه ای رو ارسال کنیم و داخل اون تابع دوباره یه آرایه ۱۰۰۰ خونه ای تعریف کینیم تا آرایه دریافتی رو توش ذخیره کنیم، یعنی عملا یه ۱۰۰۰ خونه حافظه رو الکی اشغال کردیم اما راه بهتر این بود که آدرس اون آرایه رو ارسال کنیم و در تابع این آدرس رو دریافت کنیم و دیگه یه آرایه ۱۰۰۰ خونه ای مجبور نباشیم تعریف کنیم.(البته این موضوع تو کامپیوتر شاید زیاد مهم نباشه، ولی تو میکرو چون حافظه اش کم هستش، خیلی میتونه این موضوع مهم باشه)

 
مثال برنامه نویسی ۲ (این روش مختص زبان ++C هستش)

 
مثال برنامه نویسی ۳ (مختص زبان C و ++C >>> البته تو زبان ++C روش ساده تر بالا هم هستش که میتونید استفاده کنید ولی برا زبان C فقط همین روش رو میتونید استفاده کنید >>> و این روش تو زبان C اسمش تا جایی که میدونم “ارسال از طریق ارجاع” نیست چون ارجاع برا زبان ++C هستش و این که این روشی که من در زیر استفاده کردم اسمش چیه خودمم نمیدونم.)
خب برا فهمیدن این مثال باید مطلب مربوط به اشاره گر ها رو خونده باشید ، تو خط ۲ اومدیم تابع رو اعلان کردیم و تابع یه پارامتر از نوع اشاره گر داره که آدرس متغییر هایی از نوع int رو داخل خودش ذخیره میکنه، تو خط ۸ میایم و آدرس متغییر Data رو به تابع ارسال میکنیم و تابع این آدرس رو میگیره و در اشاره گر MyData ذخیره میکنه.

 
۳) ارسال از طریق ارجاع ثابت

  • همانند روش بالا آدرس متغییر ارسال میشه.
  • تابع نمیتونه مقدار متغییر رو تغییر بده، بر خلاف روش بالا(از این نظر شبیه ارسال از طریق مقدار هستش)
  • تابع میتواند یه متغییر ارسال کند(اونم به کمک return، چون نمیتواند مقدار متغییر اون آدرس ها رو تغییر بده)
  • فرق “ارسال از طریق ارجاع ثابت” با “ارسال از طریق مقدار” :
    اگه اون مثال بالا(آرایه ۱۰۰۰ خونه ای) رو خونده باشید، میفهمید که برای جلوگیری از استفاده بی مورد از حافظه اومدیم از روش “ارسال از طریق ارجاع” استفاده کردیم، این روش(“ارسال از طریق ارجاع ثابت”) هم مثل روش “ارسال از طریق ارجاع” هستش فقط با این تفاوت که تابع نمیتونه مقدار دریافتیش رو تغییر بده، مثلا فک کنید که میخوایم یه آرایه ۱۰۰۰ تایی رو به تابع فرستیم، اولا که معلومه باید ا روش ارجاع استفاده کنیم و نه مقدار، ولی دوس نداریم مقدار این آرایه توسط تابع تغییر داده بشه، لذا به جای استفاده از روش “ارسال از طریق ارجاع” میایم و از روش “ارسال از طریق ارجاع ثابت” استفاده میکنیم.

 
مثال برنامه نویسی ۴ (این روش مختص زبان ++C هستش)

 
مثال برنامه نویسی ۵ (مختص زبان C و ++C >>> البته تو زبان ++C روش ساده تر بالا هم هستش که میتونید استفاده کنید ولی برا زبان C فقط همین روش رو میتونید استفاده کنید >>> و این روش تو زبان C اسمش تا جایی که میدونم “ارسال از طریق ارجاع ثابت” نیست چون ارجاع برا زبان ++C هستش و این که این روشی که من در زیر استفاده کردم اسمش چیه خودمم نمیدونم.)

 
 
مطالعه بیشتر + مثال های فراوان : خوندن بخش ۱۰-۵ و ۱۱-۵ از فصل ۵(توابع) از کتاب “دکتر احمد فراهانی” رو بخونید
 
چیزایی که نگفتم

  • مثال هایی از ارسال آرایه/انواع متغییر به تابع در تمامی روش ها
  • در میکرو کنترلرها ارسال انواع متغییر(که متغییر های ۱و۲و۴ بایتی داریم و آرایه ها که اندازشون توسط ما تعیین میشه) به کدوم روش بهتر هستش و باعث کاهش حجم کدهای پروژه میشود؟ ترجمه فایل AVR ATmega16 Memories و این که آدرس حافظه تو میکرو چند بایتی هستش و اگه ۳ بایتی هستش باید بگم که ارسال متغییر های زیر ۳ بایتی به روش آدرس از نظر مصرف حافظه درست نیست و…

 
فعلا یا علی.

پسورد فایل های سایت :
www.dmf313.ir
مهدی دمیرچیلو جنگ ما فتح قدس را در پی خواهد داشت (امام خمینی) >>>>>> اگر از صدام بگذریم، اگر مسأله قدس را فراموش کنیم، اگر از جنایت های امریکا بگذریم از آل سعود نخواهیم گذشت. ان‌شاالله اندوه دلمان را را در وقت مناسب با انتقام از امریکا و ال سعود برطرف خواهیم کرد و داغ و حسرت حلاوت این جنایت بزرگ را بر دلشان خواهیم گذاشت و با برپایی جشن پیروزی حق بر جنود کفر و نفاق و آزادی کعبه از دست نااهلان و نامحرمان به مسجد الحرام وارد خواهیم شد (امام خمینی)
ارسال دیدگاه
6

1) تعداد حروف غیر فارسی از حروف فارسی بیشتر باشه دیدگاه به صورت خودکار حذف میشه.

2) به موارد درخواست پروژه/کد آماده و سوالاتی که بلد نباشم پاسخ داده نمیشه.

3) برای گزاشتن کدهاتون از این سایت استفاده کنید : debian

  1. Avatar

    مهمان

    مریم

    من توی کدویژن ، با struct یه کد نوشتم. قراره struct به عنوان ورودی وارد یک تابع با خروجی void بشه وروی یه سری از پارامتر های اون تغییراتی انجام بشه. وقتی از پوینتر استفاده نکنم که تغییر اعمال نمیشه. وقتی هم استفاده میکنم خطا میده.
    خطا ها هم همه به دلیل اینه که نه متغیر ورودی تابع رو struct میشناسه و نه اصلا اون تابع رو به عنوان تابع در نظر میگیره.
    باید چیکار کنم؟ sad

    1397/05/25
    09:17
    • مهدی دمیرچیلو

      نویسنده این مطلب

      مهدی دمیرچیلو

      کدتو بفرست.
      از سایت زیر برا دادن کدات بهم استفاده کن.
      لینک کدتو هم برام بفرست
      http://paste.debian.net

      1397/05/25
      10:19
      • Avatar

        مهمان

        maryam

        http://paste.debian.net/1038312/
        تابع مورد نظر رو قبل از main گفتم.

        1397/05/26
        06:15
        • مهدی دمیرچیلو

          نویسنده این مطلب

          مهدی دمیرچیلو

          خب یه موردی
          الان نوشتی
          void CheckDrug(drug *d){
          که خب ورودی تابع فوق به صورت اشاره گر هستش و دستور زیر اشتباهه
          d.flog1
          و درستش اینه :
          d->flog1

          1397/05/26
          09:31
  2. Avatar

    مهمان

    یاسر

    عالی بود

    1396/01/18
    11:36
  3. Avatar

    مهمان

    محمد حسين

    مثل همیشه عالی بود

    1394/12/22
    04:41