انواع فراخوانی و مقادیری که توابع برمی گردانند
همانطوریکه قبلا” گفتیم ، توابع از نظر تعداد مقادیری که به تابع فراخواننده
برمی گردانند به سه دسته تقسیم می شوند که یک دسته از آنها ( توابعی که هیچ
مقداری را برنمی گردانند ) را مورد بررسی قرار داده ایم .
توابع در زبان C به دو روش فراخوانی می شوند که عبارتند از : ۱
فراخوانی توسط ارزش (Call by value). دراین روش مقدار آرگومان تابع ، در
پارامتر متناظر با آن کپی می شود . لذا هرگونه تغییری در پارامترها هیچگونه
تاثیری در مقدار آرگومان ها نخواهد داشت . بنابراین در روش فراخوانی توسط ارزش
هیچ مقداری توسط پارامترها وآرگومانها به تابع فراخواننده ، برگردانده نمیشوند.
ولی می توان فقط یک مقدار را با استفاده از دستور return به تابع فراخواننده
برگرداند . مقداری که توسط این دستور به تابع فراخواننده برگردانده می شود، در
نام تابع فراخوانده شده قرار میگیرد. دستور return به دو صورت زیر بکار میرود: return( 1)
(َ۲) (مقدار) return
دستور return در حالت (۱) صرفا” خاتمه اجرای تابع را مشخص می کند و هیچگونه
مقداری را به تابع فراخواننده برنمی گرداند. در حالت (۲) ضمن اعلام خاتمه اجرای
تابع ، مقداری را نیز به تابع فراخواننده برمی گرداند ( مثال ۱ ) .
مثال ۱: main)(
{
int t=10 ;
printf(“\n t=%d/square is:”/t);
printf(“%d”/aqr(t ));
}
eqr(int x)
{
int y ;
y=x*x;
return(y );
}
خروجی حاصل از اجرای برنامه مثال ۱ به صورت زیر است : t=10/aqurare is:100
در مثال ۱ تابع sqr برای انجام عمل توان نوشته شده است که پارامتر آن x بوده
و از نوع “صحیح ” است ( به چگونگی تعریف نوع پارامتر دقت شود ). پس از فراخوانی
تابع sqr مقدار آرگومان t (10) در پارامتر x کپی می شود و از این لحظه به بعد
هیچ کاری با t نیست . در این تابع ، نتیجه عمل در متغیر y قرار می گیرد و سپس
توسط دستور return مقدار متغیر y به تابع فراخواننده برگردانده می شود . این
مقدار در نام تابع ((t)sqr) قرار می گیرد .
۲
فراخوانی توسط ارجاع (Call by reference) . در این روش ، آدرس آرگومان
در پارامتر کپی می شود . لذا در داخل تابع فراخوانده شده ، آدرس آرگومان برای
دسترسی به آرگومان مورداستفاده قرار میگیرد و این بدان معنی است که درفراخوانی
توسط ارجاع ، پارامترها حاوی آدرس های آرگومان ها هستند. لذا در فراخوانی توسط
ارجاع باید آدرس آرگومان بجای مقدار آرگومان به تابع فراخواننده منتقل گردد .
بحث بیشتر در این مورد را به مطالعه اشاره گرها (pointer) موکول می کنیم .
مثال ۲: برنامه ای که کاراکترهایی را از ورودی خوانده و تشخیص می دهد آیا
کاراکتر وارد شده a، b، و یا غیر از این دو حرف بوده است . ضمنا” این برنامه
قبل از انجام عمل مقایسه ، با استفاده از یک تابع کاراکترهای خوانده شده را به
حروف کوچک تبدیل می کند ( کد اسکی حروف بزرگ درباره ۶۵ و ۹۱ است که اگر به این
بازه ۳۲ واحد اضافه شود کد اسکی حروف کوچک حاصل خواهد شد ) . main)(
{
char ch ;
printf(“\n type a character: ” );
ch=getcha )(;
switch(ch)
{
case ‘a’:
printf(“\n you typed the”);
printf(” character ‘a’” );
break ;
case ‘b’:
printf(“\n you typed the”);
printf(” character ‘b’” );
break ;
default:
printf(“\n you typed no ‘a’”);
printf(” and no ‘b’” );
}
}
getcha)(
{
char cl ;
cl=getch )(;
if(cl>64 && cl<91)
cl+=32 ;
return(cl );
}
نمونه ای از خروجی حاصل از اجرای برنامه مثال ۲ : type a character: s
you typed no ‘a’ and no ‘b’
تعریف توابع در داخل یکدیگر امکان پذیرنیست ، اما فراخوانی سطوح مختلف تابع
ممکن است . این مطلب در مثال ۳ مشاهده می شود .
مثال ۳: برنامه ای که با استفاده از چند تابع ، دو عدد را از ورودی خوانده و
با محاسبه مجموع مربعات آن دو ، آنها را به خروجی منتقل می کند . main)(
{
int num1/num2 ;
printf(“\n type two number:” );
scanf(%d%d”/&num1/&num2 );
printf(“\nsum of square is:”);
printf(“%d/sumsqr(num1/num2));
}
sumsqr(j/k)
int j /k ;
{
return(sum(sqr(j)/sqr(k )));
}
sqr(z)
int z ;
{
return(z*z);
}
sum(x/y)
int x/y ;
{
return(x+y);
}
نمونه ای از خروجی حاصل از اجرای برنامه مثال ۳ : type two number : 12 9
sum of square is:225
در مثال ۳از ۳ز تابع به نامهای sumsqr، sqr،و sumو استفاده شده است . وظیفه
تابع sumsqr محاسبه مجموع مربعات دو عدد num1و num2و است که برای این کار ، دو
تابع sumو sqrو را فراخوانی می کند . تابع sqr در دو بار فراخوانی ، مربع دو
عدد num1و num2و را محاسبه کرده و تحویل تابع sum می دهد . این تابع مجموع دو
پارامتر خود را که همان مربعات دو عدد num1و num2و هستند ، محاسبه می کند و به گرداند .
دیدگاه خود را بیان کنید.
باید وارد سایت شده باشید برای دیدگاه دادن