为什么要讨论这个话题呢?这个话题起源于我今天打开 Leetcode 之后看到的两行代码。
int a[5] = {0, 1, 2, 3, 4}; vector<int> v4(a, *(&a + 1));
我就好奇了这个用的是哪个构造函数。
*(&a + 1)
究竟指的是什么,这是令我费解的,调试了一下发现它指的是数组的最后,所以用的是range constructor。那么就往我们一层一层的剥开,深入理解一下吧。要理解这个主要理解
a
和&a
即可,而理解这两个我们主要从它们的类型入手,所以,它们类型都是什么?
其实a
的类型是int*
,而&a
的类型是int(*)[5]
。int(*p1)[5] = &a; int* p2 = a;
我们都很熟悉的是
int*
类型的指针偏移一位就是一维数组的下一个元素,本例中的p2
偏移一位也就是p2+1
指向的元素是 1。那么我们做个扩展,int(*)[5]
类型的指针偏移一位的下一个元素是什么?对于这个问题,我们主要理解加 1 的操作偏移的长度是多少即可。对于int*
类型加 1 移动了sizeof(int)
的长度,这是我们知道的。那么int(*)[5]
实际上原理是一样的,因为它的类型是 5 个长度的数组,因此它的加 1 操作偏移的长度是sizeof(int)*5
,因此&a+1
实际上指向了a
这个数组的末尾,因为这是指向数组的指针的缘故,我们再对它取值*(&a+1)
就得到了数组a
最后的地址。测试代码:
int* p3 = *(&a + 1); cout << *a << endl; cout << *(&a) << endl; cout << a << endl; cout << &a[0] << endl; cout << "============" << endl; cout << p3 << endl; cout << &a[4] + 1 << endl;
结果
0 0133FDF8 0133FDF8 0133FDF8 ============ 0133FE0C 0133FE0C