PDA

View Full Version : سوال: یه سوال راجع به اشاره گر



storm_saeed
سه شنبه 17 دی 1392, 20:43 عصر
سلام دوستان کد زیر روببینید

void change(int *c,int d){
*c = d;
}
void change2(int *c, int &d){
c = &d;
}
void change3(int *c, int *d){
c = d;
}
int main(){
int *b ;
int c = 1,d=14;
b = &c;
change(b,d);//or change2(b,d) or change3(b,&d)
cout <<* b;
return 0;
}

چرا اگه change رو صدا بزنیم 14 رونشون میده ولی اگه به جای change , تابع change2 یا change3رو صدا بزنیم مقدار 1 رو نشون میده
ممنون

کامبیز اسدزاده
سه شنبه 17 دی 1392, 21:05 عصر
چون در تابع change2 و change3 متغیر c تنها به مقدار اولیه خودشون اشاره دارند ولی در change اشاره شده به آدرس یا همان (مقدار آدرس مورد نظر) یعنی d برای همین در تابع change مقدار 14 و در دو تابع بعدی مقدار خود c یعنی 1 رو برمیگردونه.

storm_saeed
سه شنبه 17 دی 1392, 21:19 عصر
منظورتونو نفهمیدم میشه یکم بیشتر توضیح بدید ممنون
چرا موقعی که تو این تابع ها مقدار *cرو پرینت میکنم مقدار 14 رو میده ولی بیرون از این تابع 1 میشه مقدار *c

کامبیز اسدزاده
سه شنبه 17 دی 1392, 21:39 عصر
منظورتونو نفهمیدم میشه یکم بیشتر توضیح بدید ممنون
چرا موقعی که تو این تابع ها مقدار *cرو پرینت میکنم مقدار 14 رو میده ولی بیرون از این تابع 1 میشه مقدار *c

ببینید شما مقدار c رو در داخل تابع main به این حالا int c = 1 و مقدار d رو d = 14 دادید.
خیلی تو در تو شدن متغیر های d حالا اینطور که من درک کردم اینو شما در تابع change با نوشتن *c = d; دارید میگید که آدرس c اشاره کنه به d که 14 هست.
ولی در دو تا تابع بعدی c اشاره ای نداره به جایی فقط مقداری که بهش اختصاص داده شده رو برمیگردونه.

omidshaman
سه شنبه 17 دی 1392, 22:50 عصر
change2 , change3 که واضحه با هم برابرن .
حالا چرا مقدار عوض نمیشه ؟
چون C توی تابع و b داخل main آدرس هاشون یکی نیست فقط مقدار داخلشون که یک آدرس از نوع int هست یکیه.
یعنی c داخل تابع با b داخل main فرق می کنه فقط از نظر مقداری که داخلشونه برابرن .
این کد رو تست کن متوجه میشی چی می گم

#include <iostream>
using namespace std;
void change(int *c,int d){
*c = d;
}
void change2(int *c, int &d){
cout <<&c<<"\n";
c = &d;
}
void change3(int *c, int *d){
c = d;
}
int main(){
int *b ;
int c = 1,d=14;
b = &c;
cout <<&b<<"\n";
change2(b,d);//or change2(b,d) or change3(b,&d)


return 0;
}

rahnema1
سه شنبه 17 دی 1392, 22:58 عصر
سلام
شاید بهتر باشه یه کم دقیق تر بشیم
در هر سه تابع، آرگیومنت اول توسط مقدار پاس میشه نه توسط رفرنس بنابراین نباید از این تابع ها انتظار داشته باشیم که در آن آرگیومنت تغییر ایجاد کنند بنابراین عملکرد تابع 2 و3 مشخص شد
اما اینکه چرا تابع اول در مقدار آرگیونت ورودی تغییر ایجاد می کنه؟ علتش اینه که تغییری که ایجاد میشه در متغیر ورودی نیست یعنی در آدرس (به عنوان آرگیومنت ورودی) تغییر ایجاد نمی شه بلکه در «مقداری که اون آدرس بهش اشاره» می کنه تغییر ایجاد میشه

storm_saeed
سه شنبه 17 دی 1392, 23:12 عصر
حالا اگه مثلا change2 رو به شکل

*c =d
بنویسیم 14 میشه مقدارش یعنی مقدارشو عوض میکنه چرا ؟

rahnema1
سه شنبه 17 دی 1392, 23:21 عصر
حالا اگه مثلا change2 رو به شکل

*c =d
بنویسیم 14 میشه مقدارش یعنی مقدارشو عوض میکنه چرا ؟
یه سوال دیگه cout<<&b و cout<<b چه فرقی دارن مثالی که اقا omidshaman زدن اگه & رو برداریم یک مقدار رو چاپ میکنن

باز هم در آدرس ( به عنوان آرگیومنت ورودی تغییری ایجاد نشد) بلگه به مقداری که توسط اون آدرس بهش اشاره میشد تغییر ایجاد شد
سوال بعدی رو هم خود omidshaman جواب بدن

storm_saeed
سه شنبه 17 دی 1392, 23:23 عصر
اونو فهمیدم &b ادرس خود اشاره گر هس ولی b ادرسی هست که به اونجایی که میخواد اشاره کنه اینجا همون ادرس c هست

omidshaman
سه شنبه 17 دی 1392, 23:23 عصر
حالا اگه مثلا change2 رو به شکل

*c =d
بنویسیم 14 میشه مقدارش یعنی مقدارشو عوض میکنه چرا ؟
اگر این جوری بنویسیم میشه همون change1 یعنی میای مقداری که داخل c هست رو عوض می کنی که مقدار داخل C آدرس متغیر b داخل main برنامست

میتونی درباره change2 به این شکل هم فکر کنی این با اون معادله :
#include <iostream>
using namespace std;


int main(){
int *a;
int b=1,c=9;
a=&b;

int *temp=a;

temp=&c;//inja temp be yek mahal dg eshare mikone va a avaz nemishe

cout<<*a;

return 0;
}



یه سوال دیگه cout<<&b و cout<<b چه فرقی دارن مثالی که اقا omidshaman زدن اگه & رو برداریم یک مقدار رو چاپ میکنناین جا &b یعنی آدرس خونه ای از حافظه که محتویاتش یک int* هست ولی b یعنی آدرس خونه ای از حافظه که محتویاتش یک int هست . (منظورم همون مثالیه که خودت زدی )

storm_saeed
سه شنبه 17 دی 1392, 23:42 عصر
#include <iostream>
using namespace std;


int main(){
int *a;
int b=1,c=9;
a=&b;

int *temp=a;

temp=&c;//inja temp be yek mahal dg eshare mikone va a avaz nemishe

cout<<*a;

return 0;
}
مقدار a عوض نشد ولی اگه
به جا temp=&C

*temp=c بزاریم مقدارش عوض میشه

asdasd123123
چهارشنبه 18 دی 1392, 11:41 صبح
علامت &: این علامت دو تا کاربرد داره. اولی:

int x=2;
int& y=x;

اینجا y متغییر جدیدی نیست و آدرسش و حافظه ای که اشغال کرده همون آدرس و حافظه ی x هست. در واقع y
نام دیگر x هست. حالا چه فایده ای داره. وقتی آرگومان تابع رو به جای int x بنویسیم int& x دیگه هر تغییری که
روی x انجام میشه تو تابع، بیرون تابع هم همون تغییر انجام میشه ولی اگه & نذاریم یه متغییر محلی ایجاد میشه
که با مقدار x مقدار دهی اولیه میشه و بعد از تابع نابود میشه. دومین کاربرد هم:

int x=3;
cout<<&x;

در کنار نام متغییر یعنی آدرس متغییر. مثلا وقتی می خواهیم همه اعضای یه آرایه رو یکی یه دونه زیاد کنیم میشه
از این آدرس استفاده کرد، اینجوری:

unsigned short x_size;
cin>>x_size;
int *x=new int[x_size];
for(int i=0;i<x_size;i++) *(x+i)=i;
cout<<'\n';
for(int i=0;i<x_size;i++) cout<<*(x+i)<<'\t';
plusplus(*x,x_size);
cout<<'\n';
for(int i=0;i<x_size;i++) cout<<*(x+i)<<'\t';

این هم تابع:

void plusplus(int& x,const unsigned short& s)
{
for(int i=0;i<s;i++) (*(&x+i))++;
}

asdasd123123
چهارشنبه 18 دی 1392, 11:52 صبح
علامت *:
این یکی هم دو تا کاربرد مختلف داره. یک: اگه قبل از آدرس بیاد به معنی محتویات میشه مثلا:

int x=5;
cout<<*(&x);

حالت دوم: برای ساختن اشاره گر:

int x=7;
int* px=&x; // yani adres x ro beriz to px, vali px bayad int* bashe ta adres ro berize tosh
cout<<px; // adres x
cout<<'\n'<<*px; // mohtaviate px yani x
cout<<'\n'<<&px; // adres esharegar (adres px)

asdasd123123
چهارشنبه 18 دی 1392, 12:00 عصر
برای swap کردن دو تا متغییر از این تابع استفاده کنید:

void swp(int& x,int& y)
{
x+=y;
y=x-y;
x-=y;
}

برای تبدیل مقدار آرگومان اولی تابع به دومی هم:

void chng(int& x,const int& y)
{
x=y;
}

ولی اگه از & استفاده نکنیم متغییر های محلی که تو تابع ساخته شدن تغییر می کنن که اینجا به درد ما نمی خوره. در تابع chng آرگومان دوم به صورت & معرفی شده تا حافظه ی جدیدی
براش اختصاص داده نشه. (در واقع اون متغییر محلیه ایجاد نشه)