call by refrence در مقابل call by value - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

call by refrence در مقابل call by value

+5 امتیاز

سلام مجدد به دوستان

 

من توابعی که می نویسم هنوز درک نکردم که چرا باید by reference استفاده کنم و چرا اصلا call by value وجود داره همه رو call by refrence می کردیم خلاص
angry
سوال شده آذر 2, 1392  بوسیله ی maziyar ebrahimi (امتیاز 87)   6 13 20

2 پاسخ

+7 امتیاز
 
بهترین پاسخ

شما فرض کن این برنامه رو داری

#include <iostream>
using namespace std;
void func(int a)
{
    a++;
}
int main()
{
    int a=2;
    func(a);
    cout<<a;
}

خروجی این برنامه 2 ه چون شما a رو بصورت مقداری یا با value به func فرستادی یعنی a ای که داخل تابع هست با a داخل main فرق می کنه .

ولی حالا اگر بخوایم a ای ک داخل تابع هست همون a داخل main باشه چی ؟!

این جور مواقع به جای فرستادن مقدار a باید ادرس حافظه ای که داخلش a ذخیره شده رو بفرستیم یعنی به این شکل

#include <iostream>
using namespace std;
void func(int *a)
{
    (*a)++;
}
int main()
{
    int a=2;
    func(&a);
    cout<<a;
}

 این جا مقداری که داخل خروجی چاپ میشه 3 ه یعنی این دفعه خود a رو فرستادیم به تابع نه مقدارش رو ..

توی c++ این 2 تا معادل هم هستن .

    int *a=&b;//a address ee az noe int e,&b address b e int *a=&b yani address b ro bezar to a
    int &b=a;//moadel ebarat bala toye c++ 

پس مثال بالا رو میشه به این شکل هم نوشت بهتر هم هست به همین شکل نوشته بشه چون اشتباهات ناخواسته رو کم می کنه .

#include <iostream>
using namespace std;
void func(int& a)
{
    a++;
}
int main()
{
    int a=2;
    func(a);
    cout<<a;


}

 

حالا سوالی که پیش میاد اینه که چرا Call by refrence کنیم اصلا مگه نمیشه کد رو به این شکل هم نوشت ؟

#include <iostream>
using namespace std;
int func(int a)
{
    a++;
    return a;
}
int main()
{
    int a=2;
    a=func(a);
    cout<<a;


}

کد بالا هم درسته ولی مشکلش اینه که از نظر سرعت اجرا و مصرفه حافظه اصلا بهینه نیست چون موقع ارسال متغیر به تابع یک بار متغیر کپی میشه و همین طور موقع return َدن متغیر باز یک بار دیگه مقدار برگشتی کپی میشه تو a این کپی شدن ممکنه برای int زیاد فرقی نکنه ولی برای یک class که مثلا 100 تا فیلد داره خیلی به چشم میاد . از اون طرف موقع ارسال پارامتر به متغیر و زمانی که برنامه داخل تابع هستش 2 تا کپی از متغیر تو حافظه داریم که اینم یعنی مصرف حافظه 2 برابر بیشتر از اونی که نیازه !

می رسیم به سوال شما چرا اصلا call by value داریم وقتی که call by refrence این قدر بهتره ؟

شما وقتی که با refrence متغیر رو به تابع می فرستین گاهی اوقات ممکنه چند  تا مشکل پیش بیاد :

1_ در صورت تغییر دادن  متغیر به صورت اشتباه  داخل تابع خود متغیر هم عوض میشه  (برای حل این مشکل میشه با const & هم فرستاد متغیر رو )

2_ در صورتی که  شما در حال نوشتن برنامه به شکل موازی باشین و قرار باشه که تابع به شکل موازی با جایی که صدا زده شده اجرا بشه در صورت فرستادن متغیر با refrence  اگر متغیر از محلی که اون جا صدا زده شده پاک بشه برنامه به مشکل بر می خوره .

3_ بعضی وقت ها نیاز دارین که کپی انجام بشه این جا میشه هم با refrence فرستاد هم با value ولی فرستادن با مقدار این جور جا ها سریع تره چون به کامپایلر اجازه optimize کردن کد رو میده .

type pow2(type& a)
{
     type b=a;
    //do things on b;
    return b;
}

//or 
type pow2(type a)//faster
{
    //do things on a;
    return a;
}

در مورد اشاره گر ها هم در لینک روبرو توضیحات خوبی داده شده : آموزش کار با اشاره گر ها

پاسخ داده شده آذر 3, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد آذر 3, 1392 بوسیله ی مصطفی ساتکی
+1 امتیاز
به طور واضح و صریح اگه بخوام بگم

شما هنگامی که توی تابع byref ورودی میگیری اگر توی متغییر تغییر ایجاد بشه توی تابع هم ایجاد میشه

اما هنگامی که از byval  استفاده میکنی تابع فقط مقدار متغییر را میگید و کاری به منبع نداررد
پاسخ داده شده فروردین 29, 1393 بوسیله ی Fire360Boy (امتیاز 2,524)   8 24 43
...