The difference between pointers and arrays
I have seen in many places that an array is introduced as a pointer. This is technically not correct. Arrays are not pointer. So what is it? It is like any other variable in C++.
Take a look at this code:
1 2
|
int arr[3]={3,4,5};
cout<<arr;
| |
You may say: "Look there, arr is an address, who says it's not a pointer?"
And I say: this code prints out an address. So var is an address?
Let me explain:
All the variables can be manipulated in the memory by their addresses. CPU uses these addresses to fetch them, change them and save them. So, all variables have an address (not only those that you pointed to them). We can find out the address of a variable by (&) operator, in form of:
1 2
|
int* ptr=&intvar;
// Now the address of intvar is in ptr
| |
An array is just a sequence of variables. But there is a rule, that C++ looks arrays as if they were pointers. What does it means? It means that if you write arr, compiler takes it as &arr[0] (except in three conditions that I'll tell you soon), that is the address of the first element of the array. It has a type "pointer to T" where T is the type of array elements (that is int in our example). If you add 1 to it it will point to the second element of the array.
So it takes &arr as what?
It is one of the exceptions where the rule does not apply. It takes it as a pointer to array. It will again point to the first element of the array, but if you add one to this pointer, it will point to the address of the place right after the last element of the array (just like you skipped the array). It is a pointer to the whole the array. The value of &arr and arr is the same (address of the first element). But their type is different. Here &arr has type "pointer to the array of T" (compare it to the type of arr).
Look at this
1 2 3 4 5
|
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;
| |
First cout: Prints out the "value" of arr[0].
Second cout: Prints out the "address" of arr[0].
Third cout: Again prints out the "address" of arr[0].
Forth cout: Prints out the address of the array, that is again the address of arr[0].
And this:
1 2 3 4 5
|
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;
| |
First cout: Prints out the "value" of arr[0] plus one.
Second cout: Prints out the "address" of arr[1].
Third cout: Again prints out the "address" of arr[1] .
Forth cout: Prints out the first address of memory after the array.
Comparison
Similarities, each with an example:
1) (*) can be used for both.
1 2 3 4 5 6 7 8
|
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) Subscription can be used for both
1 2 3 4 5 6 7 8
|
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) A pointer can be used as an array.
1 2 3 4 5 6 7
|
int *ptr=new int[3];
ptr[0]=12;
ptr[2]=3;
cout<<ptr[2];
/* output */
3
| |
4) An array can have a type of pointer. That means the elements of it can be pointers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
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) All arrays will be passed to functions as a pointer, which means you can't actually send an array to a function. So function(char[]) is equal to function(char*).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
#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;
}
| |
Differences:
1) A pointer is a place in memory that keeps address of another place inside, while an array is a single, preallocated chunk of contiguous elements (all of the same type), fixed in size and location.
3) Array like pointers can't be initialized at definition like arrays.
1 2
|
char car[3]={'a','b',66};
char* cpt=new char[3]; //No way to be initialized here.
| |
4) When we allocate memory for a pointer to use it as a dynamic array. The memory can be resized or freed later. But this is not the case for arrays.
For example:
1 2 3
|
char* pta=new char[12];
//Using pta
delete[] pta;
| |
3) They produce different assembly code. Look and compare:
1 2 3 4 5 6 7 8 9 10
|
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;
}
| |
Will have an assembly like this:
1 2 3 4 5 6
|
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
| |
Hope to be useful...
Refferences:
http://67.40.109.61/torek/c/index.html
http://c-faq.com/questions.html