ورود کاربران VIP سرزمین دانلود، مرجع دانلود و آموزش رایگان نرم افزار

منوی سایت



تفاوت ارسال پارامترهای تابع به صورت مقدار، ارجاع و اشاره گر


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


int increase(int x, int count = 1) // count variable has a default value: 1
{
   x += count; // The copy of x will be changed, not the orginal x sent from caller
   return x;
}
int main(int argc, char* argv[])
{
   int i = 10;
   int j = increase(i, 5); // The first parameter is a variable and the second is a constant
   cout << "i = " << i << "n"; // i = 10
   cout << "j = " << j << "n"; // j = 15
 
   j = increase(10, 5); // Both parameters are constant!
   cout << "j = " << j << "n"; // j = 15
   return 0;

 

 

ارسال پارامتر به صورت ارجاع
این حالت دو تفاوت عمده با روش ارسال با مقدار دارد: اول این که خود متغیر اصلی به تابع ارسال شده و هر گونه تغییری که تابع روی متغیر بدهد، روی متغیر اصلی اعمال خواهد شد. دوم  اینکه به همین دلیل، نمی توان عدد ثابت را به عنوان پارامتر ارسال کرد! چون در این صورت متغیری وجود نخواهد داشت که تابع با آن کار کند. نکته دیگر این که این متغیرها نمی توانند مقدار  پیش فرض داشته باشند.
برای معرفی یک پارامتر به صورت ارجاع از علامت & استفاده می کنیم. در مثال زیر، تنها تابع increase تغییر کرده است دقت کنید که در اینجا متغیر i پس از فراخوانی تابع تغییر خواهد کرد، ضمنا خط ماقبل آخر خطایی ایجاد می کند، چرا؟

 

int increase(int &x, int count = 1) // The first parameter is declared by reference, but the second is declared by value
{
   x += count;
   return x;
}
 
int main(int argc, char* argv[])
{
   int i = 10;
   int j = increase(i, 5);
   cout << "i = " << i << "n"; // i = 15
   cout << "j = " << j << "n"; // j = 15
 
   j = increase(10, 5); //WRONG, since the first parameter can not be constant
 
   return 0;
}

 


ارسال پارامتر به صورت اشاره گر
در این روش به جای اینکه خود پارامتر ارسال شود، آدرس آن ارسال می شود و لذا هر گونه تغییری در محتوای این آدرس سبب خواهد شد که متغیر اصلی هم تغییر کند. از این نظر این روش کاملا مشابه روش ارجاع است، لیکن تفاوت در اینجا است که چون اشاره گر NULL می توانیم داشته باشیم، می توان برای متغیرهای اشاره گر مقدار پیش فرض (غالبا NULL) هم تعریف کرد.

 

int increase(int *x, int count = 1) // The first parameter is declared as a pointer
{
   (*x) += count;
   return x;
}
 
int main(int argc, char* argv[])
{
   int i = 10;
   int j = increase(&i, 5);
   cout << "i = " << i << "n"; // i = 15
   cout << "j = " << j << "n"; // j = 15
   return 0;
}
 

 

چه زمانی بهتر است از ارسال با اشاره گر استفاده کنیم؟
1. اگر تابعی داریم که چند پارامتر خروجی دارد، می توانیم پارامترهای خروجی را در لیست پارامترهای تابع و به صورت اشاره گر تعریف کنیم تا تابع آنها را پر کرده و تحویل ما دهد. مثلا فرض  کنید که تابعی داریم که میانگین و انحراف معیار یک آرایه را حساب می کند. در این صورت می توانیم به شکل زیر عمل کنیم:

 

 

int StdDev(double* pData, int len, double* pMean, double* pStdDev)
{
   if( !pData || !pMean || (len < 1) ) return -1; // Indicate an error
   *pMean = 0;
   for (int i = 0; i < len; i++)
      *pMean += pData[i];
   *pMean /= (double)len;
   if(! pStdDev) return -2; // Indicate another error
   *pStdDev = 0;
   if(len < 2) return 0; // No Error
 
   for(int i = 0; i < len; i++)
      (*pStdDev) += (pData[i] - (*pMean)) * (pData[i] - (*pMean));
 
   *pStdDev = sqrt( (*pStdDev) / (len - 1) );
   return 0;
}
 

 


2. اگر می خواهیم یک شیء (متغیر از نوع کلاس) را به تابعی ارسال کنیم، بهتر است که آن را به صورت اشاره گر یا ارجاع ارسال کنیم، چرا که کلاس حجم زیادی از حافظه را می گیرد و اگر ارسال با مقدار را استفاده کنیم، تابع سازنده ی کپی آن کلاس فراخوانی شده و یک کپی از آن روی پشته ایجاد می شود که حاوی تمام متغیرها و توابع کلاس است! لذا اصلا صلاح نیست که کلاسها را به صورت مقدار به توابع ارسال کنیم

.


( بدون کامنت - اولین کامنت را شما بنویسید )



 



سوالات و نظرات کاربران در مورد این مطلب

هنوز نظری در مورد این مطلب ارسال نشده است. شما اولین نفر باشید!

نکات مهم :

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

* نام 
آدرس ايميل (برای دریافت پاسخ از طریق ایمیل)
* شماره موبایل (برای دریافت پاسخ از طریق SMS)
توجه: ایمیل و موبایل شما فقط برای دریافت پاسخ سایت بوده و نمایش داده نمیشود.
* متن

* کد امنیتی
کد امنیتی


(اگر کد امنیتی واضح نیست، روی آن کلیک کنید تا عوض شود)
 


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

سرزمین دانلود را دنبال کنید !

عضویت در خبرنامه سرزمین دانلود

با وارد کردن ایمیل خود و سپس تایید آن، جدیدترین مطالب و نرم افزار ها برای شما ارسال می شود:



------------------------------------------