صفحه 1:
اشاره گرها

صفحه 2:
در درس مباني کامپیوتر با اشاره گرها آشنا شدیم و نحوه استفاده و کاربرد آنها رابررسي کردیم.در این قسمت ابتدا يادوري از مباحث گذشته آورده میشوده.سپس به ذکر مباحث پیشرفته تري از اشاره گرها مي پردازيم.

صفحه 3:
اشاره گرها : ۰ اشاره گرها در »++ کاربردهای فراوانی دارند.زیرادارای قابلیتهای بسیاری هستند که تعدادی از آنها عبارتند از: * بهبود کارائی بسیاری از توابع * دسترسی آسان به عناصر آرایه ها * تسهیل انجام کاربارشته هاو آرایه ها * انتقال آرایه هاورشته ها به توابع * ارسال آرگومان ها ازطریق فراخوانی با ارجاع © تخصیص حافظه پویا ؟ ایجاد ساختمان داده هاثی نظیرلیستهای پیوندی

صفحه 4:
اآدرس هاواشاره گرها: * اشاره گر چیست؟ ؟ اشاره گر یک متغیر است که آدرس یک متفیر دیگر را در خود نگه میدارد. * حافظه کامپیوتر مجموعه ای از چندین بایت است. * هر بایت دارای یک شماره ردیف است. ۴ شماره ردیف هر بایت از حافظه را آدرس آن محل از حافظه گویند. * آدرس اولین بایتی از حافظه که به متغیر اختصاص می یابد.آدرس آن متغیر می نامیم. به شکل زیر توجه کنید:

صفحه 5:
متفیرهای اشاره گر: * تعريف متفیراشاره گردر ++ به صورت زیر عمل می کنیم: :متغير * نوع * © int *ptr; ۴ که در اینجا :: به معنی تعریف اشاره گر می باشد. * دليل اين نوع تعريف نيز اين مى باشد كه كاميايلر نيازمند اين است كه بداند اين اشاره كر به جه نوع متغيرى اشاره ميكند.

صفحه 6:
عملگرهای اشاره گر: int a=5,b; int *ptr; ptr = &a; b=*ptr; ؟ عملگر »6 آدرس عملوند خودرامشخص می کند. * عملكر * محتویات جائی را مشخص می نماید که عملوندش به آن اشاره می کند. * به عملگر *# .عملكر دسترسی به اطلاعات یا عملگر غیرمستقیم میگویند. در اکثر کتب برنامه نویسی به این عملگر, نام عملگر محتوا اطلاق شده است زیرابیانگر محتوای یک متغیر است.

صفحه 7:
حال به مثال زیر توجه کنید: int varl=11, var2=22; int *ptr; ptr=&var1; cout<<"ptr point to “<<&varl<<"& ptr contents is”<<*ptr; ptr=&var2; cout<<"ptr point to “<<&var2<<"& ptr contents is”<<* ptr; return 0; خروجي این برنامه عبارت است از: int main () { ptr point to Ox8f4ffff2 & ptr contents is 11 ptr point to Ox8f4ffffO & ptr contents is 22

صفحه 8:
اشاره گر به ۷0[0: ee "5 معيولا آدرسی که در یک اشاره گر قرار میگیردباید همنوع با اشاره گر ؟ براي مثال نمی توان آدرس یک متغیر 1031] رادر یک اشاره گر از نوع 0 جایگزین کنید. ‎Lol ®‏ یک نوع اشاره گر همه منظوره وجود دارد که می تواند به هرنوع داده ای اشاره کند. ‏© اینگونه اشاره گرها دارای کاربرد ویژه و معینی نظیر انتقال اشاره گر به تابعی هستند که بطور مستقل برروی انواع داده ای مختلف عمل میکند. که به صورت زیر تعریف می شود: ‏:نام متغي ر* ‎١/010‏

صفحه 9:
int *intptr, a=3; float *floatptr, b=4; ud gi oe void *ptr; ‏به مثال زیر توجه كنيد‎ HOK /Error 3 Error floatptr = &b; //OK ptr = &a; //OK ptr = &b; //OK توضیح مثال: برطبق تعریف بالا آدرس متفیر 8را نمیتوان در متفیر ۲ ذخيره كرد ونيز آدرس متغير (آرا هم نمی توان در متغير 11781211 ذخيره كرد.اما آدرس هر دو متغير هو را می توان در متغیر ۵۲ که از نوع 010لا است ذخیره کرد.

صفحه 10:
اعمال روی اشاره گرها: اعمالي که مي توان برروي اشاره گرها انجام داد عبارتند از؛ “عمل انتساب اشاره كرهابه يكديكر *اعمال محاسباتي جمع وتفریق “عمل مقايسه اشاره كرها

صفحه 11:
اعمال محاسباتی بر روی اشاره گرها: * اعمال جمع و تفریق را می توان بر روی اشاره گرها انجام داد. با افزایش یک واحدبه اشاره گر به اندازه طول نوع اشاره گر به آن اضافه می شود. * به عنوان مثال اگر 0 اشاره گری از نوع ]۲0[ باشد که محل ۰ حافظه اشاره می نماید 0++ موجب می شودکه 0 به عدد صحیح بعدی اشاره کند. و ۵0 برابر ۱۰۰۴ شود.

صفحه 12:
مقایسه اشاره گرها: اشاره گرها را نیز مي توان با عملگرهاي رابطه اي مقایسه کرد. به عنوان مثال به دستورات زیر توجه کنید: برليقايسه محتولیمحل‌شارم ‏ [02* << 01* برلي‌قایسه محلي‌که لشارم گر به لنجا لشارم مي‌کند 02 == ‎PL‏ ‏براي مثال دستور زیر معتبر است به شرطي که 0 و 0۷ هردو اشاره گر به يك نوع داده (مثلا 101 ) باشند. ‎if (px<py)‏ ‎printf ("px points to lower memory than‏ ‎py")‏ : printf ("px points to upper memory than = py")

صفحه 13:
انتقال اشاره گر به تابع: * وقتى كه یک اشاره گر به یک تابع گذر داده می‌شود. در واقع آدرس آن قلم از داده به تابع فرستاده می‌شود. © هر گونه تغییراتی که در محتوای آدرس مورد نظر انجام گیرد. هم در تابع فراخوانده شده و هم در برنامه یا تابع فراخواننده تأثیر می‌گذارد . ؟ پارامتر متناظر تابعی که یک آدرس را به عنوان آر گومان دریافت می‌کند . باید یک اشاره گر باشد .

صفحه 14:
پارامتر متناظر تابعی که یک آدرس را به عنوان آر گومان دریافت می‌کند . باید یک اشاره‌گر باشد . # include <stdio.h> void add (int *) ; void main () { int count = 7; printf("the original value of count is %d\n" , count) ; add (& count) ; printf ("the new value of count is %d\n" , count) ; } void add (int *countptr) ++ (*countptr) ; /* increments count in main */ 1 خروجي: حي ‎the original value of count is‏ 7 the new value of count is 8

صفحه 15:
مثال: برنامه زیر. تفاوت بین آرگومانهای معمولی که بوسیله مقدارعبور داده می شوند و آر گومانهای اشاره گر را که بوسیله مرجع عبور داده می اشوند روشن مسی سزد ;void funcl (int u, int v) ; void func2 (int *pu, int *pv ) () void main 21 با ۱ : : ۱۱۲ ۷ 23 ; printf (“\n Before calling funcl :u=%d v=%d",u,v) ;funcl(u, v ) ; printf (“\n After calling funcl :u=%d v=%d",u,v) ; printf (“\n Before calling func2 :u=%d v=%d",u,v) ; func2(&u , &v ) ; printf (“\n After calling func2 :u=%d v=%d",u,v) ;Qgetch {

صفحه 16:
void funcl (int u, int v) } ;u=0 :۷ ۶0 ; printf (“\n Within funcl :u=%d v=%d",u,v) ; return { void func2 (int *pu, int *pv ) } ; pu = 0* : pv = 0* ; printf (“\n Within func2 :*pu=%d *مان‎ 900 " , ‏لام* , نام*‎ ( : ۵ Before calling funcl : Within funcl : ۱ x After calling funcl : ‏خروجي:‎ 86۲0۲6 ‏و۵11۱‎ 2 ‏2عصدم صاحا]آلالا‎ : After calling func2 :

صفحه 17:
اشاره‌گر و آرایه: ۱ * بین اشاره گرها و آرایه‌ها رابطه نزدیکی وجود دارد . نام یک آرایه در واقع اشاره گری به اولین عنصر آرایه است. ‎char str[18], *p;‏ ‎p = str;‏ * اكر بخواهيم به ينجمين عنصر در 5:1 دسترسى داشته باشيم » مى توانيم اين كار را به دو روش زير انجام دهيم : [5]4 يا *(4ج+م) 1 کاراکتر مخصوص ۷( تج

صفحه 18:
x{i] = 11 x[i] = 12 x{i] = 13 xli] = 14 x{i] = 15 Ve = (K+), ۱۱ + ( ۱۲- + We xt, ‏للم دعر‎ 1o=(x+i), x{i] = 72& x[i] = 74& x{i] = 76& x[i] = 78& x[i] = 7a& x[i] = 7c& x+i= 72 xt+i = 74 x+i = 76 x+i = 78 xt+i = 7a x+i = 7c

صفحه 19:
مدیریت حافظه : عملگر های ۲6۷۷ و ‎delete‏ ++ روش ديكرىبرلىب دست آوردنقسمتهايىاز حافظه با لستفاده از عملگر ۱6۷۷ فرلهم‌ساخته. لین‌عملگر از سيستم عامل حافظه لیب ا طولمشخص‌رمی‌گیردو بکلشارده گر که به نقطه شروع آنلشارد میکند را بر ميكردلند Student *pSt; 1) pSt = new Student; حافظه به لنداززه ی که‌لنشجو لخذ میشود || 2) pSt = new Student[10]; حافظه برلین گهداریلطلاعات ۱ دلنشجو از سیستم گرفته میشود ||

صفحه 20:
* امثال * تکه برنامه ای بنویسید که تعداد المانهای یک آرایه صحیح را گرفته و با توجه به مقدار وارد شده یک آرايه از نوع صحیح ایجاد نماید int *x,n cin>>n x = new int [n];

صفحه 21:
عملگر 06۱616 : اگر در برنامه خود با استفاده از عملگر ‎MEW‏ ۰ مقدار زيادي حافظه بگیریم آنگاه تمام حافظه موجود در اختیار برنامه خواهد بود . براي برگرداندن حافظه گرفته شده توسط دستور ‎delete Js 5) new‏ استفاده مي كنيم . البته با خاتمه اجراي برنامه » حافظه گرفته شده توسط دستور ‎NeW‏ 42 صورت اتوماتيك به سیستم بر میگردد و احتياجي به دستور 06۱646 نیست .

صفحه 22:
اشاره گر هایی به اشیا : اشیا مي توانند به انواع داده اي ساده و آرایه ها اشاره کنند . تعریف کلاس زیر را در نظر بگیرید : به عنوان مثال دستور زیر براي ایجاد يك کلاس استفاده میشود . Distance dist; ‏مي توان اشاره گري به صورت زیر تعریف کرد که به انواع داده اي از نوع اين‎ : ‏کلاس اشاره کند‎ Distance *ptr;

صفحه 23:
مبتوان از عملگر هاي ۱6۷۷ و 06666 نیز استفاده کرد. ‎Distance *ptr = new Distance;‏ ‎Distance‏ ۱۵۷ آدرس بسك شي‌جدید که در حافظه لیجاد میشود را برمیگردلند و لین‌آدرس‌در متغیر 00۲ نگهداري‌ميشود. دسترسي به اعضا : براي دسترسي به اعضاي يك شي داده وقتي اشاره گري به آن نسبت داده ایم باید از علامت خاصي به شکل زیر استفاده کنیم : ‎ptr->get() ‎: ‏البته از این روش نیز میتوان استفاده کرد‎ ‎*(ptr).get()

صفحه 24:
|تمرین *؟ یک کلاس برای نگهداری اطلاعات دانشجو تعریف نمایید. * توابع مناسب برای مقداردهی به متغیرهای عضو کلاس و نمایش اطلاعات كلاس را تعريف نماييد * یک اشاره گر از نوع ]51010611 تعریف نمایید * فضای لازم برای نگهداری اطلاعات یک دانشجو را از سیستم بگیرید * با استفاده از توابع عضو کلاس پس از مقدار دهی به شی دانشجو اطلاعات وارد شده را نمایش دهید. ؟ حافظه اخذ شده را به سیستم بر گردانید © حال مجدداً با استفاده از همان اشاره گر فضا برای نگهداری اطلاعات ۳ دانشجو را اخذ نمایید و پس از گرفتن اطلاعات دانشجویان, آنرا نمایش داده و حافظه را به سیستم بر گردانید.

صفحه 25:
۴ در صورتی که تخصیص حافظه بصورت آرایه ای باشد باید آزادسازی حافظه به شکل زیر انجام گیرد: ۳0| » ‎ptr = new int[n];‏ ® 9

صفحه 26:
ليست پیوندی 5۴| ۱۳۷ ۴ تعریف : مجموعه ای از گره ها که هر گره حداقل شامل یک فیلد داده ویک فیلد اشاره گر است. *؟ اشاره گر هر گره از نوع خود گره است. * هر گره به وسیله ی اشاره گر خود به گره بعدی اشاره می کند.

صفحه 27:
- عمليات ليست پیوندی - ايجاد ليست - درج كره در ليست - حذف گره از لیست - جستجو در لیست - مرتب سازى ليست - معكوس كردن ليست وا 2 Feb 25 Mer. 15 A linked list

صفحه 28:
پیاده سازی با اشاره گر ۴ تعریف یک نود * لازم است اين مسئله مشخص شود كه فيلدهاى ما جه نوع داده اى هستند.(به عنوان مثال مى توان یک کاراکتر) ‎class CNode‏ 3 { ‎private:‏ ‎char data;‏ ‎CNode *link;‏ ‎public:‏ ‎CNode(char d , CNode* I=NULL);‏ 1

صفحه 29:
class CLinkList 4 private: CNode *first,*last; public: CLinkList(); CLinkList(const CLinkList &!); void InsertFirst(char new_char); void InsertAfter(CNode *pNode , char new_char); void InsertBefore(CNode *pNode , char new_char); void InsertLast(char new_char); void Deleteltem(CNode *pNode); char GetltemData(int Itemindex); void Display()const; CNode* Find(char ch); void DestroyList(); ~CLinkList();

صفحه 30:
CNode *t = new CNode(new_char, first); first = t; if(tlast) last = first; درج كره در ابتداى ليست للها 8 688 :- ب ‎vo — 888 06‏

صفحه 31:
اضافه كردن به ابتداى ليست newN ‏سوه‎ ‎A first B 0 D E|0

صفحه 32:
اضافه کردن به ابتدای لیست-ادامه newhode —, first B 9 * ‏و‎ E|0 newNode > link = first;

صفحه 33:
اضافه کردن به ابتدای لیست-ادامه ۱۳9 0 8 اه ط ا« 0 ‎first B‏ first = newNode;

صفحه 34:
اضافه کردن به ابتدای لیست-دامه —" first B c +) D 80

صفحه 35:
نمایش لیست پیوندی (پیمایش) void CLinkList ::Display() { if( !first ) return; //no node Node *temp = first; while(temp) //traverse list cout << temp data; temp = temp link; //next node

صفحه 36:
اضافه کردن عنصر جدید * البته برای کاربردهای مختلف اضافه کردن فرق می کند. & ما در اینجا اضافه کردن عنصر جدید بعد از یک عنصر مشخص را نشان می دهیم. ۴ مراحل کار: ۱) نصب عنصر جدید ۲) تنظیم اشاره گرهای مربوط به عنصر جدید

صفحه 37:
curNode. newNode—~ first

صفحه 38:
اضافه کردن عنصر جدید-دامه curNode. A B ‏ظ يم‎ | 0 ١ newNod 5 first newNode > link = curNode > link ;

صفحه 39:
اضافه کردن عنصر جدید-ادامه curNode. A B (= ‏ظ‎ | 0 newNode—4 ¢ first curNode > link = newNode ;

صفحه 40:
اضافه کردن عنصر جدیددامه first

صفحه 41:
اضافه کردن عنصر جدیدادامه void CLinkList::InsertAfter(CNode *pNode , char new_char) { CNode*newNode = new CNode(new_char); newNode-link = curNodelink ; — //assign newNode curNode—link = newNode ; //assign curNode }

صفحه 42:
* مراحل کار: ۱) تنظیم اشاره گرها ۲) حذف کردن گره (آزاد کردن حافظه)

صفحه 43:
حذف عنصر از ابتدای لیست پیوندی curNode *|oB 0 oD ‏اكه‎ 0 first

صفحه 44:
ink; حذف عنصر از لیست پیوندی-ادامه curNode 5 9 0 هه first = first > first

صفحه 45:
حذف عنصر از ابتدای لیست پیوندی-دامه delete cur; first

صفحه 46:
حذف عنصر از لیست پیوندی-ادامه (6 ‎oD OE} 0‏ 0 و ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎Node *temp = first; ‎ ‎ ‎temp ‎ ‎first ‎ ‎ ‎ ‎

صفحه 47:
حذف عنصر از لیست پیوندی-ادامه (6 و temp while( temp > link != cur) temp = temp > link; first

صفحه 48:
حذف عنصر از لیست پیوندی-ادامه (6 0 اظه هه ‎c‏ و اه ۹ temp while( temp > link != cur) temp = temp > link;

صفحه 49:
حذف عنصر از لیست پیوندی-ادامه (6 - ‏إن‎ => 0 oD ۳ temp temp > link = cur > link; first

صفحه 50:
حذف عنصر از لیست پیوندی-ادامه temp delete cur; اده first

صفحه 51:
حذف عنصر از لیست پیوندی-ادامه if( cur == first ) { first = first > link; delete cur; return; 1 Node *temp = first; while( temp link != cur) temp = temp > link; temp link = cur link; delete cur; void CLinkList::Deleteltem(CNode *cur) 1

صفحه 52:
2 تمرین ؟ کلاس لیست پیوندی که 0۲0101006 آن در اسلایدهای قبل آورده شده است را پیاده سازی نمایید. * برای نمایش لیست پیوندی در صورتی که در محیط )91لا5 ۷ برنامه نویسی میکنید در تابع ۵15012۷ یک اشاره گر از نوع ‎CLIStBOX‏ گرفته شود و درون لیست نمایش اطلاعات صورت پذیرد. دیالوگهای مناسب جهت اضافه و حذف را طراحی نموده و پیامهای مناسب نیز نمایش داده شود.

صفحه 53:
ليست هاى حلقوى * به وسيله ى اتصال آخرين كره به اولين كره مى توان ليست حلقوى را توليد كرد. * دراين كونه ليست ها به راحتى مى توان از آخر ليست به اول ليست يرش كرد.

صفحه 54:
نمونه ای از لیست حلقوی first

صفحه 55:
ليست هاى ييوندى دوكانه ( دو طرفه ) * مشكل اساسى ليست هاى يك طرفه عدم دسترسى به كره قبلى * ليست هاى دوكانه با اضافه كردن يك اشاره كر به كرهى قبلى اين مشكل را حل كرده است. 1 i A doubly linked list

صفحه 56:
انواع لیست های پیوندی دو گانه لیست دوطرفه ی ساده لیست دوطرفه ی حلقوی first ‏امس‎ first ‏مب‎

صفحه 57:
اضافه کردن عنصر به لیست دوطرفه ساده newEle first A B D E

صفحه 58:
اضافه كردن عنصر به ليست دوطرفه ساده-ادامه newEle > next = cur > next;

صفحه 59:
اضافه كردن عنصر به ليست دوطرفه ساده-ادامه newEle cur > next = newEle;

صفحه 60:
اضافه كردن عنصر به لیست دوطرفه ساده-ادامه cur > next = newEle;

صفحه 61:
اضافه كردن عنصر به لیست دوطرفه ساده-ادامه newEle cur 5 (newEle > next) > pre = newEle;

صفحه 62:
اضافه كردن عنصر به ليست دوطرفه ساده-ادامه cur newEle ۱ A B 8 D E

صفحه 63:
؟ اگر بخواهیم عنصر ۱6۷۷۱6 را به ابتدای لیست اضافه کنیم؟ * اگر بخواهیم عنصر ۱6۷۷۶۱6 را به انتهای لیست اضافه کنیم؟ * اكر ليست خالى باشد؟

صفحه 64:
حذف از لیست دوطر فه ساده cur

صفحه 65:
حذف از لیست دوطرفه ساده -ادامه cur A B Cc D 3 1 (cur > next ) > pre = cur > pre;

صفحه 66:
حذف از لیست دوطرفه ساده-ادامه cur (cur > pre ) > next = cur > next;

صفحه 67:
pre (cur > pre ) > next = cur > next; حذف از لیست دوطرفه ساده -ادامه ۱۵| pre | | 1 next pre next}—

صفحه 68:
حذف از لیست دوطرفه ساده -ادامه next 1 next +. عنم لم ‎pre‏ | next first

صفحه 69:
* اگر بخواهیم عنصر ابتدای لیست را حذف کنیم؟ * اگر بخواهیم عنصر ابتدای لیست را حذف کنیم؟ ۴ اگر لیست خالی باشد؟

صفحه 70:
* اپراتورهای زیر را در کلاس ا5أام) تعریف نمایید * +: این عملگر مشابه افزودن به انتهای لیست عمل ميكند * عملگر -: این عملگر بدنبال یک کارکتر در لیست میگردد و در صورت وجود این عنصر در لیست آنرا حذف میکند © عمگر عملگر یک لیست را در لیست دیگر کپی میکند * عملگر --: این عملگر دو لیست را با هم مقایسه نموده و در صورتی که با هم برابر باشند مقدار ](] و در غیر اینصورت مقدار ‎FALSE‏ ‏برمیگرداند * عملكر [] كه يك انديس كرفته و مقدار موجود در گره با اندیس وارد شده را برميكرداند. ()101 00۵6۲۵۲۵۲][)1۳1 10۱2۲

صفحه 71:
: اشاره گر ۲۳5 * توابع عضو هر شى به یک اشاره گر جادوبی به نام 015 دسترسی دارند که به خود شی اشاره میکند. ؟ معنای وجود این متغیر در کلاس یعنی هر شی آدرس خود در خافظه را میداند و يا تعبیر دیگر اينکه هر شی خودش را ميبيند و خودش را میشناسد.

صفحه 72:
class where it private: char charArr[10]; public: void reveal() { cout<< “\nMy object’s address is:"<<this; i ; ۱ ‏ا‎ ‎void main() 1 ‏ا وت يي ا‎ where w1,w2; ‏توص ا‎ WL. reveal); WA. reved(); vant <<“ul Odes & “<<8&uAl; ‏فص‎ > Oddress ‏:سم >>" ص‎

صفحه 73:
اکاربر دهای اشاره گر ‎this‏ * يكى از پر کاربردترین کاربردها زمانی است که میخواهیم خروجی یک تابع عضو خود شی و یا ادرس خود شی باشد. ؟ کاربرد دیگر زمانی است که میخواهیم خود شی را بعنوان آرگومان یک تابع ارسال نماییم * فرض كنيد تابعى داريم كه یک شی را گرفته و اطلاعات آنرا نمایش دهد. ما میخواهیم همین تابع نمایش دادن بصورت یک تابع عضو کلاس نیز باشد. ‎sly‏ استفاده از تابع موجود میتوانیم از اشاره گر 05 استفاده نماییم.

اشاره گرها مقدمه: در درس مباني كامپيوتر با اشاره گرها آش نا ش ديم و نح وه اس تفاده و ك اربرد آنه ا رابررس ي ك رديم.در اين قس مت ابت دا ي ادآوري از مب احث گذش ته آورده ميشود،سپس به ذكر مباحث پيشرفته تري از اشاره گرها مي پردازيم. اشاره گرها : ‏ ‏ ‏ ‏ ‏ ‏ ‏ ‏ اشاره گرها در ++cكاربردهاي فراواني دارند،زيراداراي قابليتهاي بسياري هستند كه تعدادي از آنها عبارتند از: بهبود كارائي بسياري از توابع دسترسي آسان به عناصر آرايه ها تسهيل انجام كاربارشته هاو آرايه ها انتقال آرايه هاورشته ها به توابع ارسال آرگومان ها ازطريق فراخواني با ارجاع تخصيص حافظه پويا ايجاد ساختمان داده هائي نظيرليستهاي پيوندي آدرس هاواشاره گرها: ‏ ‏ ‏ ‏ ‏ ‏ اشاره گر چيست؟ اشاره گر يك متغير است كه آدرس يك متغير ديگر را در خود نگه ميدارد. حافظه كامپيوتر مجموعه اي از چندين بايت است. هر بايت داراي يك شماره رديف است. شماره رديف هر بايت از حافظه را آدرس آن محل از حافظه گويند. آدرس اولين بايتي از حافظه كه به متغير اختصاص مي يابد،آدرس آن متغير مي ناميم .به شكل زير توجه كنيد: ‏pa مقدارa آدرس a متغيرهاي اشاره گر: تعريف متغيراشاره گردر ++cبه صورت زير عمل مي كنيم: نوع  ;متغير * ; int *ptr كه در اينجا * به معني تعريف اشاره گر مي باشد. دليل اين نوع تعريف نيز اين مي باشد كه كامپايلر نيازمند اين است كه بداند اين اشاره گر به چه نوع متغيري اشاره ميكند. عملگرهاي اشاره گر: ;int a=5,b ;int *ptr ;ptr = &a ;b=*ptr ‏ ‏ ‏ ‏ ‏ ‏ ‏ عملگر & آدرس عملوند خودرامشخص مي كند. عملگر * محتويات جائي را مشخص مي نمايدكه عملوندش به آن اشاره مي كند. به عملگر * ،عملگر دسترسي به اطالعات يا عملگر غيرمستقيم ميگويند. در اكثر كتب برنامه نويسي به اين عملگر ،نام عملگر محتوا اطالق شده است زيرابيانگر محتواي يك متغير است. :حال به مثال زير توجه كنيد int main ( ) { int var1=11, var2=22; int *ptr; ptr=&var1; cout<<”ptr point to “<<&var1<<”& ptr contents is”<<*ptr; ptr=&var2; cout<<”ptr point to “<<&var2<<”& ptr contents is”<<* ptr; return 0; } :خروجي اين برنامه عبارت است از ptr point to 0x8f4ffff2 & ptr contents is 11 ptr point to 0x8f4ffff0 & ptr contents is 22 اشاره گر به :void ‏ ‏ ‏ ‏ معموال آدرسي كه در يك اشاره گر قرار ميگيردبايد همنوع با اشاره گر باشد. براي مثال نمي توان آدرس يك متغير floatرادر يك اشاره گر از نوع intجايگزين كنيد. اما يك نوع اشاره گر همه منظوره وجود دارد كه مي تواند به هرنوع داده اي اشاره كند. اينگونه اشاره گرها داراي كاربرد ويژه و معيني نظير انتقال اشاره گر به تابعي هستند كه بطور مستقل برروي انواع داده اي مختلف عمل ميكند. كه به صورت زير تعريف مي شود: ;نام متغير* void به مثال زير توجه كنيد: توضيح مثال: ;int *intptr, a=3 ;float *floatptr, b=4 ;void *ptr ;intptr = &a //OK ;intptr = &b //Error ‏floatptr = &a; //Error ‏floatptr = &b; //OK ;ptr = &a //OK ;ptr = &b //OK برطب\\ق تعري\\ف باال آدرس متغ\\ير aرا نميت\\وان در متغ\\ير floatptrذخ\\يره كرد ون\\يز آدرس متغ\\ير bرا هم نمي توان در متغير intptrذخيره كرد.اما آدرس هر دو متغير ‏aو bرا مي ت\\وان در متغ\\ير ptrك\\ه از ن\\وع voidاس\\ت ذخيره كرد. اعمال روي اشاره گرها: اعمالي كه مي توان برروي اشاره گرها انجام داد عبارتند از: •عمل انتساب اشاره گرهابه يكديگر •اعمال محاسباتي جمع وتفريق •عمل مقايسه اشاره گرها اعمال محاسباتي بر روي اشاره گرها: اعمال جمع و تفريق را مي توان بر روي اشاره گرها انجام داد. با افزايش يك واحدبه اشاره گر به اندازه طول نوع اشاره گر به آن اضافه مي شود. به عنوان مثال اگر pاشاره گري از نوع intباشد كه محل 1000حافظه اشاره مي نمايد ++pموجب مي شودكه pبه عدد صحيح بعدي اشاره كند .و pبرابر 1004شود. مقايسه اشاره گرها: اشاره گرها را نيز مي توان با عملگرهاي رابطه اي مقايسه كرد. به عنوان مثال به دستورات زير توجه كنيد: براي مقايسه محتواي محل اشاره ;*p1 == *p2 براي مقايسه محلي كه اشاره گر به آنجا اشاره مي كندp1 == p2 براي مثال دستور زير معتبر است به شرطي كه pxو pyهردو اشاره گر به يك نوع داده (مثال ) intباشند. )if (px<py ‏printf ("px points to lower memory than )"; py ‏else ‏printf ("px points to upper memory than )"; py انتقال اشاره‌گر به تابع: وقتي كه يك اشاره‌گر به يك تابع گذر داده مي‌شود ،در واقع آدرس آن قلم از داده به تابع فرستاده مي‌شود. هر گونه تغييراتي كه در محتواي آدرس مورد نظر انجام گيرد، هم در تابع فراخوانده شده و هم در برنامه يا تابع فراخواننده تأثير مي‌گذارد . پارامتر متناظر تابعي كه يك آدرس را به عنوان آرگومان دريافت مي‌كند ،بايد يك اشاره‌گر باشد . بايد، پارامتر متناظر تابعي كه يك آدرس را به عنوان آرگومان دريافت مي‌كند . يك اشاره‌گر باشد # include <stdio.h> void add (int *) ; void main ( ) { int count = 7 ; printf("the original value of count is %d\n" , count) ; add (& count) ; printf ("the new value of count is %d\n" , count) ; } void add (int *countptr) { ++ (*countptr) ; /* increments count in main */ } the original value of count is 7 the new value of count is 8 :خروجي تفاوت بين آرگومانهاي معم\\ولي که بوس\\يله مق\\دارعبور، برنامه زير:مثال داده مي شوند و آرگومانهاي اشاره گر را که بوس\\يله مرج\\ع عب\\ور داده مي . ش\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\وند روش\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ن مي سازد ; void func1 ( int u , int v ) ; void func2 ( int *pu , int *pv ) ) ( void main { ; int u = 1 ; int v = 3 ; printf (“\n Before calling func1 ; func1(u , v ) ; printf (“\n After calling func1 : ; printf (“\n Before calling func2 ; func2(&u , &v ) ; printf (“\n After calling func2 : ;)(getch } … : u=%d v=%d " , u , v ) u=%d v=%d " , u , v ) : u=%d v=%d " , u , v ) u=%d v=%d " , u , v ) :ادامه مثال void func1 ( int u , int v { ;u=0 ;v=0 ; printf (“\n Within func1 ; return } void func2 ( int *pu , int { ; pu = 0* ; pv = 0* ; printf (“\n Within func2 ; return } ) : u=%d v=%d " , u , v ) *pv ) : *pu=%d *pv=%d " , *pu , *pv ) Before calling func1 : u = 1 v = 3 Within func1 : u=0 v=0 After calling func1 : u=1 v=3 Before calling func2 : u = 1 v = 3 Within func2 : *pu = 0 *pv = 0 After calling func2 : u=0 v=0 :خروجي اشاره‌گر و آرايه: ‏ ‏ بين اشاره‌گرها و آرايه‌ها رابطه نزديكي وجود دارد .نام يک آرايه در واقع اشاره گري به اولين عنصر آرايه است. ; char str[18] , *p ;p = str اگر بخواهيم به پنجمين عنصر در strدسترسي داشته باشيم ، مي‌توانيم اين كار را به دو روش زير انجام دهيم : ]str[4 كاراكتر مخصوص ‘\’0 يا *()p+4 كاراكتر مخصوص ‘\’0 ‏str ‏p 27 23 26 19 22 25 21 24 15 18 14 17 20 11 13 16 7 10 6 9 12 3 2 5 8 1 4 0 int x[6] x+2 x+3 x+4 x+5 13 14 15 12 x+1 11 x 75 10 79 74 78 73 72 7d 7c 77 76 80 7b 7a 85 81 84 7f 7e 83 82 x+i = 72 x[i] = 72& 10 = )x+i(* x[i] = 10 i=0 x+i = 74 x[i] = 74& 11 = )x+i(* x[i] = 11 i=1 x+i = 76 x[i] = 76& 12 = )x+i(* x[i] = 12 i=2 x+i = 78 x[i] = 78& 13 = )x+i(* x[i] = 13 i=3 x+i = 7a x[i] = 7a& 14 = )x+i(* x[i] = 14 i=4 x+i = 7c x[i] = 7c& 15 = )x+i(* x[i] = 15 i=5 مديريت حافظه :عملگر هاي newو delete • ++cروش ديگري ب\\راي بدس\\ت آوردن قس\\مت هايي از حافظ\\ه با استفاده از عملگر newفراهم ساخته .اين عملگر از سيس\\تم عام\\ل حافظه اي با طول مشخص مي گيردو يك اشاره گركه به نقط\\\ه شروع آن اشاره ميكند را بر ميگرداند. ;Student *pSt ;1) pSt = new Student حافظه به اندازه يك دانشجو اخذ ميشود// ;]2) pSt = new Student[10 حافظه براي نگهداري اطالعات 10دانشجو از سيستم گرفته ميشود// مثال • تكه برنامه اي بنويسيد كه تعداد المانهاي يك آرايه صحيح را گرفته و با توجه به مقدار وارد شده يك آرايه از نوع صحيح ايجاد نمايد ‏int *x,n ‏cin>>n ;]x = new int [n عملگر : delete اگ ر در برنام ه خ ود ب ا اس تفاده از عملگ ر ، newمق دار زي ادي حافظ ه بگ يريم آنگ اه تم ام حافظ ه موج ود در اختي ار برنام ه خواه د ب ود .ب راي برگرداندن حافظه گرفته ش ده توس ط دس تور newاز دس تور delete استفاده مي كنيم . ‏ptr =new SomeClass ‏delete ptr البته با خاتم ه اج راي برنام ه ،حافظ ه گرفت ه ش ده توس ط دس تور newب ه صورت اتوماتيك به سيستم بر ميگردد و احتياجي به دستور deleteنيست . اشاره گر هايي به اشيا : اشيا مي توانند به انواع داده اي ساده و آرايه ها اشاره كنند .تعري ف كالس زي ر را در نظر بگيريد : به عنوان مثال دستور زير براي ايجاد يك كالس استفاده ميشود . { Class Distance …. )(Void get { … } …. } ;Distance dist مي توان اشاره گري به صورت زير تعريف كرد كه به انواع داده اي از نوع اين كالس اشاره كند : ;Distance *ptr ميتوان از عملگر هاي newو deleteنيز استفاده كرد. ;Distance *ptr = new Distance new Distanceآدرس ي ك ش ي جدي د ك ه در حافظ ه ايج اد ميش ود را برميگرداند و اين آدرس در متغير ptrنگهداري ميشود. دسترسي به اعضا : براي دسترسي به اعضاي يك شي داده وقتي اشاره گري به آن نسبت داده ايم بايد از عالمت خاصي به شكل زير استفاده كنيم : )(ptr->get البته از اين روش نيز ميتوان استفاده كرد : )(*(ptr).get تمرين ‏ ‏ ‏ ‏ ‏ ‏ ‏ يك كالس براي نگهداري اطالعات دانشجو تعريف نماييد. توابع مناسب براي مقداردهي به متغيرهاي عضو كالس و نمايش اطالعات كالس را تعريف نماييد يك اشاره گر از نوع Studentتعريف نماييد فضاي الزم براي نگهداري اطالعات يك دانشجو را از سيستم بگيريد با استفاده از توابع عضو كالس پس از مقدار دهي به شي دانشجو اطالعات وارد شده را نمايش دهيد. حافظه اخذ شده را به سيستم برگردانيد حال مجددًا با استفاده از همان اشاره گر فضا براي نگهداري اطالعات 3 دانشجو را اخذ نماييد و پس از گرفتن اطالعات دانشجويان ،آنرا نمايش داده و حافظه را به سيستم برگردانيد. در صورتي كه تخصيص حافظه بصورت آرايه اي باشد بايد آزادسازي حافظه به شكل زير انجام گيرد: ; int *ptr ;] ptr = new int[n … ; delete [] ptr ليست پيوندي Link List ‏ تعريف :مجموعه ای از گره ها که هرگره حداقل شامل يک فيلد داده ويک فيلد اشاره گر است. ‏ اشاره گر هر گره از نوع خود گره است. هر گره به وسيله ی اشاره گر خود به گره بعدی اشاره می کند. ‏ 0 ‏Z ... ‏B ‏A عمليات ليست پيوندي ايجاد ليست درج گره در ليست حذف گره از ليست جستجو در ليست مرتب سازي ليست معكوس كردن ليست -و ... پياده سازي با اشاره گر ‏ تعريف يك نود الزم است اين مسئله مشخص شود که فيلدهای ما چه نوع داده ای هستند(.به عنوان مثال می توان يک کاراکتر) ‏class CNode { ‏private: ;char data ;CNode *link ‏public: ;)CNode(char d , CNode* l=NULL ;} كالس ليست پيوندي class CLinkList { private: CNode *first,*last; public: CLinkList(); CLinkList(const CLinkList &l); void InsertFirst(char new_char); void InsertAfter(CNode *pNode , char new_char); void InsertBefore(CNode *pNode , char new_char); void InsertLast(char new_char); void DeleteItem(CNode *pNode); char GetItemData(int ItemIndex); void Display()const; CNode* Find(char ch); void DestroyList(); ~CLinkList(); }; void CLinkList::InsertFirst (char new_char) { CNode *t = new CNode(new_char, first); first = t; if(!last) last = first; } درج گره در ابتداي ليست A A first first A B B C C اضافه کردن به ابتدای ليست ‏newNode 0 0 ‏E ‏D ‏C ‏B ‏A ‏first ادامه-اضافه کردن به ابتدای ليست newNode A first B C D newNode  link = first; E 0 ادامه-اضافه کردن به ابتدای ليست newNode A first B C first = newNode; D E 0 اضافه کردن به ابتدای ليست-ادامه ‏newNode 0 ‏E ‏D ‏C ‏B ‏A ‏first )نمايش ليست پيوندی (پيمايش void CLinkList ::Display() { if( !first ) return; //no node Node *temp = first; while(temp) //traverse list { cout << tempdata; temp = templink; //next node } } اضافه کردن عنصر جديد ‏ ‏ ‏ البته برای کاربردهای مختلف اضافه کردن فرق می کند. ما در اينجا اضافه کردن عنصر جديد بعد از يک عنصر مشخص را نشان می دهيم. مراحل کار: )1نصب عنصر جديد )2تنظيم اشاره گرهای مربوط به عنصر جديد درج عنصر جديد curNode first 0 newNode 0 ادامه-اضافه کردن عنصر جديد curNode first A newNode B D E 0 C newNode  link = curNode  link ; ادامه-اضافه کردن عنصر جديد curNode first A newNode B D C curNode  link = newNode ; E 0 ادامه-اضافه کردن عنصر جديد curNode first A B newNode C D E 0 ادامه-اضافه کردن عنصر جديد void CLinkList::InsertAfter(CNode *pNode , char new_char) { CNode*newNode = new CNode(new_char); newNodelink = curNodelink ; //assign newNode curNodelink = newNode ; //assign curNode } حذف عنصر از ليست پيوندی ‏ مراحل کار: )1تنظيم اشاره گرها )2حذف کردن گره (آزاد کردن حافظه) حذف عنصر از ابتدای ليست پيوندی ‏curNode ِE 0 ِD ‏C ِB ِA ‏first ادامه-حذف عنصر از ليست پيوندی curNode first ِA ِB C first = first link; ِD ِE 0 حذف عنصر از ابتدای ليست پيوندی-ادامه ِE 0 ِD ‏C ;delete cur ِB ‏first ادامه-حذف عنصر از ليست پيوندی curNode first ِA ِB C temp Node *temp = first; ِD ِE 0 ادامه-حذف عنصر از ليست پيوندی curNode first ِA ِB C ِD ِE 0 temp while( temp  link != cur) temp = temp  link; ادامه-حذف عنصر از ليست پيوندی curNode first ِA ِB C ِD ِE 0 temp while( temp  link != cur) temp = temp  link; ادامه-حذف عنصر از ليست پيوندی curNode first ِA ِB C ِD temp temp  link = cur  link; ِE 0 حذف عنصر از ليست پيوندی-ادامه ِE 0 ِD ِB ‏temp ;delete cur ِA ‏first ادامه-حذف عنصر از ليست پيوندی void CLinkList::DeleteItem(CNode *cur) { if( cur == first ) { first = first  link; delete cur; return; } Node *temp = first; while( templink != cur) temp = temp  link; templink = curlink; delete cur; } تمرين كالس ليست پيوندي كه prototypeآن در اساليدهاي قبل آورده شده است را پياده سازي نماييد. ‏ براي نمايش ليست پيوندي در صورتي كه در محيط VisualCبرنامه نويسي ميكنيد در تابع Displayيك اشاره گر از نوع CListBoxگرفته شود و درون ليست نمايش اطالعات صورت پذيرد .ديالوگهاي مناسب جهت اضافه و حذف را طراحي نموده و پيامهاي مناسب نيز نمايش داده شود. ليست های حلقوی ‏ ‏ به وسيله ی اتصال آخرين گره به اولين گره می توان ليست حلقوی را توليد کرد. در اين گونه ليست ها به راحتی می توان از آخر ليست به اول ليست پرش کرد. نمونه ای از ليست حلقوی ِE ِD ‏C ِB ِA ‏first ليست های پيوندی دوگانه ( دو طرفه ) ‏ مشکل اساسی ليست های يک طرفه عدم دسترسي به گره قبلی ‏ ليست های دوگانه با اضافه کردن يک اشاره گر به گره ی قبلی اين مشكل را حل كرده است. انواع ليست های پيوندی دوگانه ليست دوطرفه ی ساده 0 ‏E ‏D ‏C ‏B ‏A ‏first 0 ليست دوطرفه ی حلقوی ‏E ‏D ‏C ‏B ‏A ‏first اضافه کردن عنصر به ليست دوطرفه ساده ‏newEle ‏C ‏cur 0 ‏E ‏D ‏next ‏pre ‏B ‏A 0 ‏first ادامه-اضافه کردن عنصر به ليست دوطرفه ساده newEle C cur 0 first A B D 0 newEle  next = cur  next; E اضافه کردن عنصر به ليست دوطرفه ساده-ادامه ‏newEle ‏C ‏cur 0 ‏E ‏D ‏B ‏A 0 ;cur  next = newEle ‏first اضافه کردن عنصر به ليست دوطرفه ساده-ادامه ‏newEle ‏C ‏cur 0 ‏E ‏D ‏B ‏A 0 ;cur  next = newEle ‏first ادامه-اضافه کردن عنصر به ليست دوطرفه ساده newEle C cur 0 first A B D 0 (newEle  next)  pre = newEle; E اضافه کردن عنصر به ليست دوطرفه ساده-ادامه ‏newEle ‏cur 0 ‏E ‏D ‏C ‏B ‏A 0 ‏first سوال ‏ اگر بخواهيم عنصر newEleرا به ابتداي ليست اضافه كنيم؟ اگر بخواهيم عنصر newEleرا به انتهاي ليست اضافه كنيم؟ ‏ اگر ليست خالي باشد؟ ‏ حذف از ليست دوطرفه ساده ‏cur 0 ‏E ‏D ‏C ‏B ‏A 0 ‏first ادامه- حذف از ليست دوطرفه ساده cur first A B C D 0 E 0 ( cur  next )  pre = cur  pre; ادامه-حذف از ليست دوطرفه ساده cur 0 first A B C D E 0 ( cur  pre )  next = cur  next; ادامه- حذف از ليست دوطرفه ساده first next next next 0 A B D E 0 pre pre pre ( cur  pre )  next = cur  next; ادامه- حذف از ليست دوطرفه ساده first next next next 0 A B D E 0 pre pre pre سوال ‏ اگر بخواهيم عنصر ابتداي ليست را حذف كنيم؟ اگر بخواهيم عنصر ابتداي ليست را حذف كنيم؟ ‏ اگر ليست خالي باشد؟ ‏ تمرين ‏ ‏ ‏ ‏ ‏ ‏ اپراتورهاي زير را در كالس CLListتعريف نماييد : +اين عملگر مشابه افزودن به انتهاي ليست عمل ميكند عملگر :-اين عملگر بدنبال يك كاركتر در ليست ميگردد و در صورت وجود اين عنصر در ليست آنرا حذف ميكند عمگر = :اين عملگر يك ليست را در ليست ديگر كپي ميكند عملگر == :اين عملگر دو ليست را با هم مقايسه نموده و در صورتي كه با هم برابر باشند مقدار TRUEو در غير اينصورت مقدار FALSE برميگرداند عملگر [] كه يك انديس گرفته و مقدار موجود در گره با انديس وارد شده را برميگرداند;char operator[](int idx). اشاره گر this توابع عضو هر شي به يك اشاره گر جادويي به نام this دسترسي دارند كه به خود شي اشاره ميكند. معناي وجود اين متغير در كالس يعني هر شي آدرس خود در خافظه را ميداند و يا تعبير ديگر اينكه هر شي خودش را ميبيند و خودش را ميشناسد. class where { private: char charArr[10]; public: void reveal() { cout<< “\nMy object’s address is:”<<this; } My objectْs address is:0012FF74 }; My objectْs address is:0012FF68 void main() w1 Address is 0012FF74 { w2 Address is 0012FF68 where w1,w2; w1. reveal(); w2. reveal(); cout <<“w1 Address is “<<&w1; cout <<“w2 Address is “<<&w2; } كاربردهاي اشاره گر this يكي از پركاربردترين كاربردها زماني است كه ميخواهيم خروجي يك تابع عضو خود شي و يا آدرس خود شي باشد. كاربرد ديگر زماني است كه ميخواهيم خود شي را بعنوان آرگومان يك تابع ارسال نماييم فرض كنيد تابعي داريم كه يك شي را گرفته و اطالعات آنرا نمايش دهد .ما ميخواهيم همين تابع نمايش دادن بصورت يك تابع عضو كالس نيز باشد .براي استفاده از تابع موجود ميتوانيم از اشاره گر thisاستفاده نماييم.

51,000 تومان