我们都知道:“数组名其实代表的是数组的第一个元素的地址”。每次在遇到的时候都是像背八股一样,但是并没有深刻的去理解它背后的意义。以至于在遇到指针加减的时候会想不通。
先来一个简单的代码:
int main() {
int arr[] = {1,2,3,4,5};
cout << sizeof(arr) << endl;
cout << &arr << endl;//00DAF9B8
cout << &arr + 1 << endl; //00DAF9C8
cout << "xxxxxxxxxxxxxxx" << endl;
cout << arr << endl;//00DAF9B8
cout << arr + 1 << endl;//00DAF9BC
system("pause");
return 0;
}
首先要知道arr是数组名,等于我们所定义的数组的第一个元素的地址!而&arr是数组的地址(它当然是从数组的第一个元素开始算啦,所以为什么首元素地址等于整体数组的地址)两者是相等的,从输出也可以看出都是00DAF9B8。但是为什么两个都是相等的,各自在+1的时候,却不同了?即:&arr+1 -->00DAF9C8;arr+1-->00DAF9BC。
瞬间感觉自己的数学观崩塌了??其实这个地方虽然arr和&arr的值是相等的,但是其实各自的含义确天差地别!!!(不要被表象所迷惑)。
如何证明我们是被表象迷惑了呢?
arr+1-->00DAF9BC ,和00DAF9B8相减得4(注意:这是16进制的4)。这个4是不是很熟悉?因为我们知道计算机的内存都是按字节存储的,所以这个4就是4个字节。也就是一个指针的内存大小,所以这个arr + 1就是指针向右移动了一格(4个字节),所以大家应该就知道它指向的单元就是数组中的元素 2
cout << *(arr + 1) << endl;//输出2
而&arr+1 -->00DAF9C8和00DAF9B8相减得10(16进制),转十进制就是16。这个16是啥?
cout << sizeof(arr) << endl;//16
你猜的没错,这两个其实就是相等的!不用怀疑。所以这个&arr+1就是指向下一个数组的首地址!!用整体法,&arr代表这个整个数组的地址,&arr+1,是+1个整体(数组的大小),那可不直接就跑到数组的外边去了,所以如果你解引用,肯定会越界:
cout << &arr + 1 << endl; //00DAF9C8
int* p =(int*) (&arr + 1);
cout << *p << endl;//越界
总结:
arr是一个指针变量(准确说是常量),说到底它是指针,所以arr+1相当于arr+sizeof(int),加了四个字节。而&arr是整个数组的地址值,是一个int类型的值,&arr+1相当于+sizeof(arr),加了一个数组的大小其实还是一个值,所以它不是指针。