تکین وب | آموزش برنامه نویسی
تکین وب | آموزش برنامه نویسی

توابع و روش فراخوانی آنها در ++C

۴ شهریور ۱۳۹۴

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

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

معرفی تابع

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

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

( لیست پارانتر های تابع ) نام تابع   < نوع بازگشتی >

}

  ; دستورات

{

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

نوع بازگشتی  همان خروجی  ای است که قرار است تابع تحویل دهد و می تواند از انواع متغیرها باشد . مثلا اگر نوع بازگشتی یک نوع عدد صحیح باشد ، باید int قرار داده شود یا اگر بخواهیم نوع بازگشتی از نوع عدد اعشاری باشد float و یا double را انتخاب می کنیم . توجه کنید که ممکن است یک تابع هیچ مقداری را برنگرداند در این صورت نوع بازگشتی از نوع پوچ یا void می باشد .

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

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

 درنهایت بعد از رعایت تمام نکات ، می توانیم بدنه یا دستورات مربوط به تابع را بین دو آکولاد بنویسیم :

int minimum(int a , int b)
{
....
}

در تکه کد بالا تابعی به اسم minimum را ملاحظه می کنید . این تابع دارای دو ورودی از نوع عدد صحیح می باشد که به وسیله کاما از هم جدا شده اند . همینطور هر کدام از این ورودی ها دارای یک نام دلخواه مثلا a و b  می باشند . خروجی تابع هم از نوع عدد صحیح می باشد . به این معنا که بعد از انجام محاسباتی که در بدنه تابع انجام می شود ، مینیمم دو عدد a و b محاسبه شده و به عنوان خروجی تحویل داده می شود .

اعلان تابع

برای اینکه تابعی را که می خواهیم در main به کار ببریم به کامپایلر اطلاع دهیم باید آن را اعلان کنیم. اعلان یک تابع در بالای main و بعد از فایل هایی که ضمیمه کردیم می باشد :

#include "iostream"
#include <stdlib.h>
using namespace std;

int minimum(int a , int b);
int main()
{
''''
}

همانطور که در تکه کد بالا مشاهده می کنید ، تابع minimum در بالای main تعریف شده است  و بعد از آن از علامت سمیکالن استفاده می شود  . دقت  کنید که اعلان تابع باید دقیقا مطابق با آن چه در تعریف تابع به کار برده می شود ، باشد . به این معنا که نوع بازگشتی ، نام تابع و نوع و تعداد متغیرهایی که در اعلان تابع به کار برده می شود ، مطابق با تعریف آن باشد اما لازم نیست نام متغیرها همان نامی باشد که در تعریف تابع به کار برده شده است .

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

فراخوانی تابع

برای اینکه بتوان از تابع در main استفاده کرد باید فراخوانی شود . فراخوانی یعنی صدا زدن تابع در جایی از main که به آن نیاز داریم :

#include "iostream"
#include <stdlib.h>
using namespace std;
int minimum(int a , int b);
int main()
{
int num1 , num2 ;
minimum (num1 , num2);
}

بعد از تعریف دو متغیر num1 و num2  تابع minimum فراخوانی شده است . توجه کنید که نباید در هنگام فراخوانی تابع نوع بازگشتی ذکر شود . بنابراین این دو متغیر به عنوان پارامترهای ورودی به این تابع فرستاده می شوند :


int minimum(int a , int b)
{
 if(a<b)
 return a;
 if(b<a)
 return b;
 return 1;
}

تکه کد بالا تعریف تابع minimum را نشان می دهد  . اگر دقت کرده باشید در جایی که این تابع را فراخواندیم ، دو متغیر num1 و num2 به عنوان ورودی های تابع وجود داشتند اما در اینجا از دو متغیر دیگر استفاده کرده ایم .باید بدانید که num1 به جای متغیر a و num2 به جای متغیر b قرار گرفته است . به این معنا که یک کپی از هر دو متغیری که در main تعریف کرده بودیم ، در این تابع قرار گرفته اند . درنهایت با انجام اعمال منطقی ، مینیمم بین آن دو عدد محاسبه و به main برگردانده شده است :

#include <iostream>
#include <stdlib.h>
using namespace std;

int minimum(int a , int b);
int main()
{
 int num1 , num2 , result;
 cout<<"2 adad vared konid : "<<endl;
 cin>>num1>>num2;
 result=minimum(num1 , num2);
 cout<<result<<endl;
 system("pause");
 return 0;
}

int minimum(int a , int b)
{
 if(a<b)
 return a;
 if(b<a)
 return b;
 return 1;
}

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

توابعی که هیچ مقداری را برنمی گردانند

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

void convert();
int main()
{
 convert();
 system("pause");
 return 0;
}

void convert()
{
int hours , minutes , seconds ;
long int time;
cout<<"enter time to be convert:"<<endl;
cin>>hours>>minutes>>seconds ;
time = (hours*60 + minutes)*60 +seconds;
cout<<time<<endl;
}

در برنامه بالا تابع ()convert در بالای main اعلان شده است . این تابع هیچ مقدار ورودی ای ندارد .نوشته شدن کلمه void در جایگاه نوع بازگشتی نشان می دهد این تابع هیچ مقداری را برنمی گرداند . علاوه براین در تعریف تابع ،  چهار متغیر تعریف شده اند و بعد از عملیات مورد نظر نتیجه بر روی صفحه نمایش داده خواهد شد . توجه کنید که این متغیرها محلی هستند . به این معنا که فقط در تابعی که تعریف شده اند می توانیم از آن ها استفاده کنیم و در خارج از تابع از بین خواهند رفت .

متغیر های محلی و سراسری

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

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

توابع بازگشتی

توابع بازگشتی به توابعی گفته می شود که در آن تابعی خودش را فراخوانی می کند . برای تعریف یک تابع بازگشتی از دستور زیر استفاده نمایید :

( به حالت توقف رسیدی )if

مسئله حالت توقف را حل کن   

else

       تابع را بار دیگر فراخوانی کن    

حال با استفاده از تکه کد زیر به بررسی این دستور  می پردازیم :

int factorial(int n)
{
if(n == 0)
return 1;
else
{
return ( n * factorial(n-1) );
}
}

این تابع ، تابع بازگشتی محاسبه فاکتوریل یک عدد را طبق دستوری که بیان کردیم ، نشان می دهد . در بدنه تابع در اولین قدم  شرط پایان ذکر شده است . به این معنا که اگر ورودی این تابع عدد ۰ بود ، ۱ برگردانده شود چرا که فاکتوریل عدد ۰ ، ۱ می شود . در غیراینصورت اعمال بعدی انجام شوند . همانطور که می دانید برای محاسبه فاکتوریل یک عدد می توان از ضرب آن عدد در فاکتوریل آن عدد منهای یک ، به جواب مورد نظر دست یافت .به عنوان مثال فرض کنید می خواهیم فاکتوریل عدد ۴ را محاسبه کنیم در این صورت طبق این فرمول باید ! (۱ – ۴) * ۴ را محاسبه کنیم . در مرحله بعد چون فاکتوریل عدد ۳ را نمیدانیم ، دوباره از همین فرمول استفاده خواهیم کرد یعنی ! (۱ – ۳) * ۳ و چون فاکتوریل عدد ۲ را نمیدانیم باید به صورت  ! (۱ – ۲) * ۲ عمل کرد . همینطور فاکتوریل عدد ۱ را به صورت  ! (۱ – ۱) * ۱ و در نهایت چون می دانیم فاکتوریل ۰ ، ۱ می شود ، پس به صورت بازگشتی مسئله های قبلی حل خواهند شد یعنی :

مقدار ! ۳ از قسمت بعد جایگزین می شود    ! (۱ – ۴) * ۴ = ! ۴

مقدار ! ۲ از قسمت بعد جایگزین می شود    ! (۱ – ۳) * ۳ = ! ۳

مقدار ! ۱ از قسمت بعد جایگزین می شود    ! (۱ – ۲) * ۲ = ! ۲

مقدار ! ۰ از قسمت بعد جایگزین می شود    ! (۱ – ۱) * ۱ = ! ۱

۱ = ! ۰

اعمال تابع فاکتوریل برای محاسبه فاکتوریل عدد ۴ :

فراخوانی اول :   در ابتدا عدد ۴ به جای ورودی تابع قرار می گیرید . پس (۴)factorial باید محاسبه شود . ۴ به تابع فرستاده می شود . چون ۰==۴ نیست ، else اجرا می شود بنابراین تابع به ازای ۳=n فراخوانی می شود .

فراخوانی دوم : برای بار دوم  چون تابع فاکتوریل در main فراخوانی شده است ، باید(۳)factorial  محاسبه شود . بنابراین دوباره عدد ۳ به عنوان ورودی تابع قرار خواهد گرفت . در تابع factorial ، چون ۰==۳ نیست else اجرا خواهد شد . بنابراین تابع به ازای ۲=n فراخوانی می شود .

فراخوانی سوم : برای بار سوم دوباره تابع factorial در main فراخوانی می شود . این بار (۲)factorial باید محاسبه شود . پس عدد ۲ به عنوان پارامتر ورودی به تابع factorial فرستاده می شود .  در تابع factorial ، چون ۰==۲ نیست else اجرا خواهد شد . بنابراین تابع به ازای ۱=n فراخوانی خواهد شد .

فراخوانی چهارم : برای بار چهارم دوباره تابع factorial در main فراخوانی می شود . این بار (۱)factorial باید محاسبه شود . پس عدد ۱به عنوان پارامتر ورودی به تابع factorial فرستاده می شود .  در تابع factorial ، چون ۰==۱ نیست else اجرا خواهد شد . . بنابراین تابع به ازای ۰=n فراخوانی خواهد شد .

در فراخوانی آخر چون عدد ۰ به عنوان ورودی به حساب می آید و شرط اول یعنی ۰==۰ برقرار است ، عدد ۱ برگردانده خواهد شد (زیرا ۱=!۰) .

در این صورت تابع فاکتوریل در بدنه خودش ، خودش را فراخوانی می کند و در نهایت بعد از پایان این مراحل مقدار فاکتوریل عدد ۴ به main برگردانده خواهد شد .

بنابراین مقدار  ۲۴ به عنوان فاکتوریل عدد ۴ در خروجی نمایش داده خواهد شد .

کد این برنامه به صورت زیر می باشد :

#include <iostream>
#include <stdlib.h>
using namespace std;
int factorial( int);
int main()
{
cout<<factorial(4);
system("pause");
return 0;
}

int factorial(int n)
{
if(n == 0)
return 1;
else
{
return ( n * factorial(n-1) );
}
}

دانلود سورس چند برنامه با تابع بازگشتی : Recursive Functions

در ضمن اگر اینستاگرامی هستید حتما @Takinweb را فالو کنید….

درباره ی عطیه رحمانی

دیدگاه ها

یک دیدگاه ارسال شده !

  1. احسان می‌گه:

    با سلام و خسته نباشید.
    اگر بخواهیم برنامه ای بنویسیم که یک تابع ریاضی به عنوان ورودی بگیرد و یه ورودی دیگه هم بگیره و در اون تابع که خودمون بهش دادیم، قرار بده و نتیجه را به ما بدهد باید چه کرد؟

دیدگاه خود را به ما بگویید.

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