刚接触指针的时候,你很可能会觉得:数组和指针基本上是同一个东西。的确,数组和指针都可以用*取值,都可以加减某个数获得别的指针,都可以用[]来取值……例如下面的代码:
int arr[5] = {2, 3, 5, 7, 9}; //定义一个数组,长度为5
int* arr_ptr = arr; //定义一个指针指向数组arr
cout << "*arr = " << *arr << " *(arr + 3) = " << *(arr + 3) << " arr[3] = " << arr[3] << endl;
cout << "*arr_ptr = " << *arr_ptr << " *(arr_ptr + 3) = " << *(arr_ptr + 3) << " arr_ptr[3] = " << arr_ptr[3] << endl;
/*
输出:
*arr = 2 *(arr + 3) = 7 arr[3] = 7
*arr_ptr = 2 *(arr_ptr + 3) = 7 arr_ptr[3] = 7
*/
嗯,看来数组和指针确实很像。但是数组和指针并不是完全等价的,一个简单的例子就是sizeof:
int arr[5]; //定义一个数组,长度为5
int* arr_ptr = arr; //定义一个指针指向数组arr
cout << "Size of arr: " << sizeof arr << endl; //输出20,20 = 4 * 5
cout << "Size of arr_ptr: " << sizeof arr_ptr << endl; //输出8(在64位系统上)
面对数组,sizeof运算符(注意sizeof不是函数)求出了这个数组所占所有空间的大小(一个int占4字节,5个int占了20字节);但是面对指针arr_ptr,sizeof直接求出了arr_ptr这个int*类型的变量的大小。在64位系统上,一个内存地址需要8字节来存储,所以sizeof arr_ptr
就是8。
利用c++的typeinfo头文件,我们还可以直接看看这些变量的类型是什么:
int arr[5] = {2, 3, 5, 7, 9}; //定义一个数组,长度为5
auto arr_ptr = arr; //定义一个指针指向数组arr
auto new_ptr = new int[5]; //new出来5个int类型对象
cout << "Type of arr: " << typeid(arr).name() << endl; //输出A5_i,表示arr是一个长度为5的int类型数组
cout << "Type of arr_ptr: " << typeid(arr_ptr).name() << endl; //输出Pi,表示arr_ptr的类型是int的指针
cout << "Type of new_ptr: " << typeid(new_ptr).name() << endl; //也输出Pi
可以发现,arr的类型是数组,而且这个类型里自带了数组的长度;而无论是直接定义出来的指针变量还是new的返回值,类型都是指针。数组和指针是两种不同的类型。
另外,数组加减一个int之后,也会变成指针;两个指针相减,则会返回long类型。
cout << "Type of (arr + 1): " << typeid(arr + 1).name() << endl; //输出Pi
cout << "Type of (arr_ptr + 1): " << typeid(arr_ptr + 1).name() << endl; //输出Pi
cout << "Type of (arr - arr_ptr): " << typeid(arr - arr_ptr).name() << endl; //输出l
另外一个区别是:指针变量是可以赋值的,一个指针可以从前指向位置1、后来指向位置2;而数组是不能被赋值的。
int arr1[5], arr2[5];
int* ptr = arr1;
ptr = arr2; //可以
arr1 = arr2; //不可以,error: array type 'int [5]' is not assignable