اولین بار است که به این وب‌سایت می‌آیید. راهنما را مطالعه کنید!
x
موسسه خیریه محک

شهر ریاضی بازی-ریاضی

چطور می‌توانم از طریق اشاره‌گر، آدرس یک متغیر را تغییر دهم؟

+1 امتیاز
890 نمایش

اگر من یک اشاره گر به int مانند p در main تعریف کنم، می‌تونم توسط دستور زیر آدرسی که p را در بردارد تغییر دهم:


p=&a;

که a متغیر دیگری از نوع int است.
حال می‌خواهم آدرس را توسط تابع زیر تغییر دهم:

void changeadd(int*a)
{
int *b;
a=b;
}

اما اگر در تابع اصلی ام، p را قبل فراخوانی تابع بالا و بعد آن چاپ کنم، می‌بینم که آدرسی تغییر نکرده.
مشکل از چیست؟
برنامه‌ای که تست نشده کار نخواهد کرد (Stroustrup, Bjarne)
پرسیده شده یکشنبه ۲۸ آبان ۱۳۹۱ در C++ توسط CPP_Crawler3  
بازتگ شده چهارشنبه ۲۱ فروردین ۱۳۹۲ توسط admin

3 پاسخ

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

تابع زیر رو در نظر می‌گیریم

void f(int x)
{
  x = 5;
}

وقتی تابع رو به صورت زیر فراخوانی کنیم

int i = 10;
f(i);
cout<<i;

انتظار داریم چه مقداری چاپ بشه؟ مسلماً ۵ نیست. چون متغیر i به صورت مقداری و کپی داخل تابع قرار گرفته. بنابراین مقدارش در داخل تابع تغییر نمی‌کنه. بلکه مقدار یه کپی از اون هست که تغییر می‌کنه.

به طور کلی اگه T یه نوع داده باشه تابعی به صورت f(T) نمی‌تونه مقدار متغیر ارسالی به تابع رو تغییر بده. همیشه یه کپی ساخته می‌شه.

این از اطلاعاتی که به عنوان یه برنامه‌نویس آشنا به C++ داریم.

اما در مورد سوال. یه تابعی داریم که یه int* رو به عنوان آرگومان می‌گیره.

اگه T رو int* در نظر بگیریم پس f(T) یه تابع با ارجاع مقداری هست. بنابراین مقدار متغیر ارسال شده یعنی int* در داخل تابع نغییر نمی‌کنه. مقدار متغیر ارسالی همون آدرس داخل اشاره‌گر ارسالی هست.

در صورتی که T رو int در نظر بگیریم پس f(T*) di تابع با ارجاع اشاره‌گری هست. بنابراین مقدارش داخل تابع تغییر می‌کنه. یعنی مقدار داخل متغیر ارسال شده به تابع نه اشاره‌گر! یعنی آدرس عوض نمی‌شه ولی مقدار داخل اشاره‌گر عوض می‌شه.

برای عوض کردن مقدار آدرس اشاره‌گر مثل زیر می‌شه عمل کرد

void f(int **p)
{
  *p = new int(4);
}

int main()
{
  int *p = new int();
  cout<<"p = "<<p<<endl;
  f(&p);
  cout<<"p = "<<p<<endl;
  return 0;
}

یا

void f(int *&p)
{
  p = new int(4);
}

int main()
{
  int *p = new int();
  cout<<"p = "<<p<<endl;
  f(p);
  cout<<"p = "<<p<<endl;
  return 0;
}
هیچ پژوهش انسانی نمی‌تواند ادعای علمی بودن داشته باشد، مگر این‌که از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)
پاسخ داده شده شنبه ۱۸ خرداد ۱۳۹۲ توسط prodo  
انتخاب شده شنبه ۱۸ خرداد ۱۳۹۲ توسط admin
+1 امتیاز

با سلام،
به نظر می رسد یک اشتباه اینجا صورت گرفته است و آن هم این است که ما در اینجا یک متغیر گلوبال داریم به نام a و یک اشاره گر گلوبال داریم به نام p و متغیری لوکال که در تابع تعریف شده است به نام b، خوب نکته اینجاست که ورودی تابع یک اشاره گر است و چون ما اشاره گری به نام a نداریم که به صورت گلوبال تعریف شده باشد، با اجرای برنامه اگر ران تایم ارُر ندهد، دستکم تابع هیچ کاری انجام نمی دهد و اشاره گر p به همان آدرسی اشاره خواهد کرد که قبلاً اشاره می کرد.

پاسخ داده شده پنجشنبه ۱۲ بهمن ۱۳۹۱ توسط sam  
0 امتیاز

دقیقا نمیدونم چرا اگر یک اشاره‌گر رو به تابعی بفرستی که اونجا یک اشاره‌گر دیگه بهش تخصیص بدی، تغییری در آدرس اون اشاره‌گر ایجاد نمیشه، ولی اگه خیلی معمولی این دستورات در تابع اصلیتون داشته باشین این اتفاق میفته:

int main(){
    int a=1;
    int *ptr =  &a;
    cout<<ptr<<endl<<*ptr<<endl;
    int b=2;
    int *p=&b;
    ptr=p;    
cout<<ptr<<endl<<*ptr<<endl;
system("pause");
return 0;
}
پاسخ داده شده دوشنبه ۹ بهمن ۱۳۹۱ توسط CPP_Crawler4