آموزش کار با اشاره گر ها در c++ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

آموزش کار با اشاره گر ها در c++

+7 امتیاز
سلام ببخشید اموزش اشاره گر هارو میخوام واینکه مثلا کجا یک چیز new میشه ..مثلا point** چیه...در کل سوال شبیه سازی هندسه هست همینجا اون ارایه هاش که در کلاس polygon هستش رو نمیفهمم..من خودم دارم c++ میخونم این قسمت هارو اصلا نمیفهمم...اگه کمکم کنین واقعا ممنون میشم
سوال شده اسفند 26, 1392  بوسیله ی programmer (امتیاز 139)   9 19 32
ویرایش شده اسفند 26, 1392 بوسیله ی BlueBlade

1 پاسخ

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

pointer یا اشاره گر  متغیری هست  که آدرس یک متغیر دیگه داخلش ذخیره میشه  .

اگر توی برنامتون یک شی داشته باشین که قابل دسترسی باشه آدرس اون شی هم اغلب اوقات  قابل دسترسیه ‌ .

اگر a یک شی باشه &a آدرس اون شی هست .

کاری که عملگر * میکنه برعکس & هست * به ما مقدار موجود داخل اشاره گر رو میده ولی & آدرس متغیر رو .

به &  address operator  و  به * derefrence operator می گن .

مثال از نحوه تعریف اشاره گر :

int* x;
//ya
int *x;

2 تا عبارت بالا رو به ترتیب میشه به این شکل تفسیر کرد.

۱ـ x یک متغیره که از نوع *int  ( اشاره گر به  int ) هستش .

۲ـ x* از نوع int هستش (یعنی x آدرسیه که مقدار داخلش از نوع int هستش )

که هر ۲ تا تعریف بالا درست هستن و معادل همدیگه هستن .

 

مثال زیر رو در نظر بگیرید :

#include <iostream>

using namespace std;
int main()
{
    int x=1;
    cout<<x<<'\n';

    int* p = &x;
    *p = 2;

    cout<< x ;
}
//khorooji :
//1
//2

توی کد بالا همون طوری که مشخصه با عوض کردن مقدار p مقدار داخل x هم عوض میشه چون x و p هر 2 به یک محل از حافظه اشاره می کنن پس عوض کردن هر کدوم باعث میشه که دیگری هم عوض بشه .

توی مثال بلا از اون جایی که int* p هم یک متغیره ما میتونیم به آدرسش دسترسی داشته باشیم به این شکل

int x = p;
int *p = &x
int **p2 = &p;

داخل کد بالا ما آدرس داخل p رو میزاریم داخل p2 .

این جا هم   int **p2 رو میشه به این اشکال نوشت

int* *p2;
int **p2;
int** p2;

عبارات بالا رو هم به همون روشی که بالا گفتم میشه به ترتیب به این شکل تفسیر کرد :

1_ p2* (مقدار داخل p2 ) از نوع اشاره گر به int هستش  ( *int )

2_**p2  ( مقدار داخل  مقدار p2 ) از نوع int هستش .

3_ p2 از نوع اشاره گر به **int هستش ( اشاره گر به *int یا  اشاره گری که به اشاره گر به int اشاره می کنه  )

که هر 3 تعریف بالا معادل هم هستن .

 

به همین ترتیب میشه *** و **** و ... رو هم تعریف کرد .

 

حالا فرض کنید که  این عبارت رو دارید :

int *x;

این جا  x رو تعریف کردین ولی مقدار اولیه ندادین برای همین به حافظه  نامشخصی اشاره می کنه .

برای مقدار اولیه دادن به اشاره گر از NULL یا nullptr استفاده می کنن

دلیل این کار هم اینه که با این کار شما در ادامه برنامه می تونید چک کنید که آیا x به حافظه خاصی اشاره می کنه یا نه .

int *x = nullptr ;
if(x==nullptr)
  //..
else 
 //...

'گرفتن حافظه برای متغیر :

برای گرفتن حافظه برای متغیر در ++C  از new استفاده می کنن

کاری که عبارت new T می کنه اینه که به اندازه متغیر  T برای ما حافظه  میگیره  و یک اشاره گر به  T ( که همون  *T  هست ) بر می گردونه .

برای مثال :

int *a = new int ; //gereftan hafeze baraye a
int *a= new int(5); //tafavotesh ba code bala ine ke inja *a meghdar avalie 5 migire

 

زمانی که از new استفاده می کنین حتما باید بعد از استفاده حافظه گرفته شده رو با استفاده از delete پاک کنید :

delete a;

برای گرفتن حافظه برای آرایه باید از new T[]l استفاده کنین

مثلا :

int *a = new int[10];

کد بالا به اندازه یک آرایه 10 عضوی برای ما حافظه می گیره و یک اشاره گر به خونه اول آرایه بر می گردونه که ما اونو داخل a میزاریم .

برای پاک کردن حافظه آرایه گرفته شده بوسیله new باید از delete[] استفاده بشه .

delete[] a;

نکته : دقت داشته باشین که استفاده از delete[] , delete به جای هم مشکل سازه  و undefined behavior هستش (یعنی برنامتون ممکنه هر اتفاقی توش بیفته مثلا اگر از delete [] به جای delete استفاده کنین برنامه احتمال داره قسمت های حیاتی از حافظه رو پاک کنه که خطرناکه )

برای ساختن آرایه 2 بعدی هم باید به این شکل عمل کنین :

int **arr;

arr = new int*[5];

for(int i=0;i<5;i++)
{
     arr[i]=new int[3];
}

کاری که کد بالا می کنه اینه که اول یک آرایه 5 تایی از *int  با استفاده از new  میسازیم که این جا new یک اشاره گر به خونه اول این آرایه بر میگردونه و از اون جایی که خونه اول از نوع *int هست پس  آدرس *int که به شکل  **int برگشت داده میشه و داخل arr گذاشته میشه .

بعد در مرجله بعد بوسیله حلقه for  داخل هر خونه از این آرایه  یک آرایه یک بعدی با اندازه 3 قرار میگیره .

 

برای پاک کردن آرایه 2 بعدی بالا  هم به این شکل عمل کنید :

for(int i=0;i<5;i++)
{
    delete[] arr[i];
}
 
delete[] arr;

واینکه مثلا کجا یک چیز new میشه ..مثلا point** چیه.

 بر اساس توضیحات بالا  **point  یک اشاره گر به یک اشاره گر به point هستش

که خود این اشاره گر به point ممکنه

1_ به یک point اشاره کنه .

2_به خونه اول یک آرایه از point ها اشاره کنه .

یعنی بسته به این که کد چی باشه و **point رو به چه شکل بهش مقدار داده باشیم ممکنه یک آرایه 2 بعدی از point ها باشه یا این که ممکنه یک اشاره گر به آدرس یک point باشه .

 

نکته  مهم : توی برنامه نویسی با ++C باید سعی بشه تا حد امکان از new استفاده نشه

برای استفاده از آرایه که سایزش زمان اجرا عوض میشه میتونین از vector استفاده کنین. به جای char* از  string  ,...

جاهایی هم که از new استفاده می کنین بهتره که از اشاره گر های هوشمند  استفاده بشه تا حافظه گرفته شده به صورت خودکار پاک بشه .

 

پاسخ داده شده اسفند 26, 1392 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
ویرایش شده شهریور 8, 1393 بوسیله ی BlueBlade
چرا از new استفاده می کنیم ؟
اینکه میگین حافظه میگیره وقتی new میکنیم مگه خود اشاره گر حافظه نداره جدا دیگه چرا براش حافظه میگیریم؟
اشاره گر یک متغیره که آدرس یک شی دیگه رو داخلش ذخیره می کنیم .
اندازه حافظه ای که اشاره گر داره فقط به اندازه نگه داری اون آدرس هستش ( داخل سیستم های 32 بیتی 4  بایت )
new یک شی دیگه رو میسازه ( حافظش میتونه خیلی از 4 بایت بیشتر باشه) و آدرس اون شی ساخته شده رو داخل اشاره گر میزاریم.
...