callcc.dev

为什么要讨论这个话题呢?这个话题起源于我今天打开 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