我在Leetcode上找到以下代码。然而,我无法理解下面两行的含义,特别是*(&a + 1)
。结果显示了一个数组a
的副本。有谁能够解释一下吗?谢谢!
int a[5] = {0, 1, 2, 3, 4};
vector<int> v4(a, *(&a + 1));
当你从数组构造向量时,通常遇到的示例如下所示:
int a[5] = {...};
vector<int> v4(a, a + 5 );
// or vector<int>(a, a+sizeof(a)/int); // automatically calculate num elems inside a
上面的示例展示了如何使用数组"a"中的所有元素来构造一个向量。在这个示例中,"a"只是数组起始元素的地址,然后你加上5得到最后一个元素的地址。更直观的写法是:
vector<int> v4(begin(a), end(a));
除非你不想在v4中拥有a的所有元素
现在,你给我们的例子是第一个例子的简写形式,在这种情况下,你不需要显式地指定数组的大小。我猜你只是对向量构造函数的第二个参数感到困惑。第二个参数只返回数组"a"的最后一个元素的地址。但是怎么做呢?
好吧,让我们来分解一下:&a返回"a[]"的地址。本质上是"a"数组的指针。现在,如果你在这个地址上加1,你将得到一个指向地址"a[0]" + sizeof a[] 的指针,它将指向地址a的最后一个元素。把这个与上面的第一个例子进行比较。你必须加5,为什么这里不是这样?因为你正在使用不同的单位。&a指向a[]的起始地址,而不是数组的第一个元素的地址。所以,你实际上是按照a[5]单位移动地址,而不是按照int单位移动。
最后,你有解引用运算符“*”来解引用指针并获取数组[]的最后一个元素的地址。
a是类型a[],&a是类型*a[],因此需要解引用才能使它们成为相同的类型,否则你会得到一个编译器错误。
简而言之,你正在使用不同的方法来获取最后一个元素的地址。+1运算符相对于你处理的类型而行事。 a + 1与"a"的起始地址加上1个整数的大小相同。 &a + 1与a[]的起始地址加上a[]的大小相同。
a
代表整个数组,它在大多数情况下会衰减成指向第一个元素的指针,但是对于一元运算符&
,它不会发生衰减。所以&a
给出的是整个数组的地址,而不是第一个元素的地址。虽然它们指向同一位置,但它们的类型不同 (int (*)[5]
和int *
),这种不同的类型会导致指针算术运算有所不同。"最初的回答"。
a
是指向第一个元素的指针,而&a
给出指针的地址,那么我不明白(&a + 1)代表什么,以及地址*(&a + 1)是什么。我的猜测是,由于a已经定义了其大小,*(&a + 1)将指向数组的末尾? - user8822312vector<int> v4( std::begin(a), std::end(a) );
。 - M.Mvector<int> v4(a, *(&a + 1));
这样的写法也可以在旧版和新版的 C++ 中使用,并且对于 C++ 程序员而言应该是相当清晰的,因为它甚至不需要除了 vector 以外的库文件。但是对于新版的 C++ 而言我非常认同您的观点。这种写法还有一个优点,就是适用于不同的容器类型。然而,我仍然看到很多人明确地声明 vector 的构造方式,这种写法更糟糕。 - doug