تیم برنامه نویسی گروه تمدن

مرجع کامل فارسی برنامه نویسی به زبان سی پلاس پلاس

  • Increase font size
  • Default font size
  • Decrease font size

تفاوت های موجود بین اشاره گر و آرایه

فرستادن به ایمیل چاپ مشاهده در قالب پی دی اف

به نام خدا

دیده شده که خیلی ها آرایه را به عنوان اشاره گر معرفی می کنند. این موضوع از لحاظ تکنیکی اشتباه است. آرایه ها، اشاره گر نیستند. پس چه هستند؟ این ها هم مثل متغیرهای دیگر در سی پلاس پلاس هستند.
بیایید نگاهی به قطعه کد زیر بیندازید:

int arr[3]={3,4,5};
cout<<arr;

احتمالا می گویید:«این جا را نگاه کن! آرایه یک آدرس است پس چگونه یک اشاره گر نیست؟»
و من می گویم: کد زیر هم یک آدرس را چاپ می کند آیا می توان گفت که متغیر یک آدرس است؟

int var;
cout<<&var;

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

int* ptr=&intvar;
// Now the address of intvar is in ptr

یک آرایه تنها دنباله ای از متغیرهاست؛ اما تحت این قانون که سی پلاس پلاس به آرایه ها به چشم اشاره گر نگاه می کند. این به چه معناست؟ این یعنی اینکه اگر arr (که منظور اسم آرایه به تنهایی است) بنویسید، کامپایلر آن را به عنوان [arr[0& در نظر می گیرد.(با سه استثناء  که در ادامه خواهم گفت) که این همان آدرس خانه ی اول از آرایه می باشد. اگر آرایه یک نوع از جنس T داشته باشد  (که در مثال ما از جنس عدد صحیح است) و به آن اشاره کرده و آن را بعلاوه 1 کنید آن به دومین خانه از آرایه اشاره خواهد نمود.
بنابراین کامپایلر arr& را چه چیزی در نظر می گیرد؟
این یکی از استثناء هایی است که قانون کلی در مورد آن صدق نکرده و آن را به عنوان اشاره گری به آرایه در نظر می گیرد. این دوباره به اولین خانه از آرایه اشاره می کند اما اگر به آن یک واحد اضافه کنید دقیقاً به آدرس خانه ی راستی بعد از آخرین خانه ی آرایه اشاره خواهد کرد. (که دقیقا مثل این است که آرایه را نادیده گرفته و از روی آن پریده باشید.) این مورد اشاره گری به تمام آرایه است. مقدار arr& و arr  (یعنی آدرس خانه ی اول) یکسان اما نوع آن ها با یکدیگر متفاوت است. اینجا arr& دارای نوعی از اشاره گری به آرایه ای از جنس T است. (این را با نوع arr مقایسه کنید.)
نگاهی به کد زیر بیندازید:

int arr[3]={3,4,5};
cout<<"First element of the array: "<<arr[0] <<endl;
cout<<"Address of the first element: "<<&arr[0] <<endl;
cout<<"Address of the array: "<<arr <<endl;
cout<<"So what is this? "<<&arr <<endl;

اولین cout «مقدار» [arr[0 را چاپ می کند.
دومین cout «آدرس»[arr[0 را چاپ می کند.
سومین cout مجددا «آدرس» [arr[0 را چاپ می کند.
چهارمین cout آدرس آرایه را چاپ می کند که مجددا آدرس [arr[0 خواهد بود.
و این کد:

int arr[3]={3,4,5};
cout<<"First element of the array: "<<arr[0]+1 <<endl;
cout<<"Address of the first element: "<<&arr[0]+1 <<endl;
cout<<"Address of the array: "<<arr +1<<endl;
cout<<"So what is this? "<<&arr +1<<endl;

اولین cout «مقدار»[arr[0 بعلاوه یک را چاپ می کند.
دومین cout «آدرس» [arr[1 را چاپ می کند
سومین cout مجددا «آدرس»[arr[1 را چاپ می کند.
چهارمین cout آدرس اولین خانه حافظه بعد از آرایه را چاپ می کند.
مقایسه
تشابهات هر کدام با یک مثال:
1. (*) می تواند برای هر دو استفاده شود.

int arr[3]={1,3,4};         //Declares an array with 3 elements
int * ptr=arr;              //Initialize pointer ptr with the address of  array arr 
cout<<*(arr+2)<<endl;
cout<<*{ptr+2)<<endl;

/* output */
4
4

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

int arr[3]={1,3,4};         //Declares an array with 3 elements
int * ptr=arr; 		 //Initialize pointer ptr with the address of  array arr
cout<<arr[2])<<endl;
cout<<ptr[2])<<endl;

/* output */
4
4

3. یک اشاره گر می تواند برای یک آرایه استفاده شود.

int *ptr=new int[3]; 
ptr[0]=12;
ptr[2]=3;
cout<<ptr[2];

/* output */
3

4. یک آرایه می تواند از نوع یک اشاره گر باشد. این به این معنی است که خانه ها می تواننداز اشاره گر ها تشکیل شده باشند.

int ar[2]={8,2};
int var1=66;
int var2=111;
int* ptarray[5];
ptarray[0]=ar;
ptarray[1]=&ar[1];  //Address of second element of array ar
ptarray[2]=&var1;
ptarray[3]=&var2;
ptarray[4]=&ar[0];
// To keep code small I use a loop
for(int i=0;i<5;i++)
	cout<<*(ptarray<i>)<<endl;

/* output */
8
2
66
111
8

5. تمام آرایه ها جهت استفاده در ورودی توابع به عنوان یک اشاره گر در نظر گرفته می شوند. این به این معنی است که شما نمی تواند واقعا یک آرایه را به یک تابع ارسال نمایید. بنابرین ([]function(char برابر با (*function(char است.

#include<iostream>
using namespace std;
void test(char v[]);

int main(){ 
	char a[53];
         //a="If a is an array, this line should generate an error";   	
	test(pta);
	return 0;
}

void test(char v[]){
	v="If v is an array, this line should generate an error";
	cout<<v<<endl;
}

تفاوت ها:
1. یک اشاره گر آدرس جایی دیگر از حافظه را در خود جای می دهد. این در حالی است که یک آرایه از پیش تکه ای از خانه های مجاور (با نوع داده ای یکسان در تمامی آن ها) را در حافظه اشغال کرده و دارای اندازه و مکان ثابت و معینی است.
2. اشاره گرها مثل آرایه ها نمی توانند در زمان تعریف، مقدار دهی اولیه شوند.

char car[3]={'a','b',66}; 
char* cpt=new char[3]; //No way to be initialized here.

3. زمانی است که حافظه ای را برای یک اشاره گر جهت استفاده در آرایه های پویا اختصاص می دهیم. در اشاره گر ها حافظه بعدا می تواند تغییر اندازه دهد و یا آزاد شود اما در مورد آرایه ها چنین نیست.

char* pta=new char[12];
//Using pta
delete[] pta;

4. این ها دارای پیاده سازی های مختلفی در کد های اسمبلی هستند. خودتان نگاه و مقایسه کنید.

int main()
{ 
	char arr[3];
	char* ptr=new char[3];

	arr[0]='C';   //Assembly is for this.  
	ptr[0]='p';   //And for this.

	return 0;
}

دارای کد اسمبلی شبیه زیر هستند.

arr[0]='C';
            mov         byte ptr [ebp-4],43h  //The code for putting one character in an array

ptr[0]='p';
            mov         ecx,dword ptr [ebp-8]  //The two line code for putting one character
            mov         byte ptr [ecx],70h     //in a place where a pointer points to  

امیدوارم مفید واقع شده باشد...

منبع: سایت cplusplus.com نوشته SiavoshKC
ترجمه و ویرایش: مرجع فارسی سی پلاس پلاس به آدرس cplusplus.ir

آخرین بروز رسانی مطلب در يكشنبه ، 5 آذر 1391 ، 17:22  

افزودن نظر

دوست عزیز و کاربر گرامی
نظرات بعد از بررسی در سایت درج خواهند شد.
مطمئنا از شنیدن انتقادهای شما خوشحال خواهیم شد.
دلیل فیلتر کردن نظرات صرفا جلوگیری از نظرات مغایر با اسلام و جمهوری اسلامی ایران می باشد. امیدواریم ما را به خاطر این کار درک نمایید. با تشکر






کد امنیتی
بازنشانی