从 C++ 中的现有数组创建子数组的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2137361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to create a sub array from an exisiting array in C++?
提问by jspcal
OK, I am trying to get a sub array from an existing array and I'm just not sure how to do it. In my example I have a very large array, but I want to create an array from the last 5 elements of the array.
好的,我正在尝试从现有数组中获取子数组,但我不知道该怎么做。在我的示例中,我有一个非常大的数组,但我想从数组的最后 5 个元素创建一个数组。
An example of what I am talking about would be:
我正在谈论的一个例子是:
int array1 = {1,2,3,...99,100};
int array2[5] = array1+95;
I know this isn't correct, but I am having some trouble getting it right. I want to get the elements 96 through 100 in array1 and put them into array2 but I don't want to copy the arrays. I just want array2 to start at the 96 element such that array1[96] and array2[0] would be pointing to the same location.
我知道这不正确,但我在正确处理时遇到了一些麻烦。我想在 array1 中获取元素 96 到 100 并将它们放入 array2 但我不想复制数组。我只希望 array2 从 96 元素开始,这样 array1[96] 和 array2[0] 将指向相同的位置。
回答by jspcal
for this:
为了这:
"such that array1[96] and array2[0] would be pointing to the same location."
you can do:
你可以做:
int *arr2 = arr1 + 96;
assert(arr2[0] == arr1[96] == 97);
回答by Chris Lutz
A reference hack from a C programmer willing to subvert the type system to get what works:
来自 C 程序员的参考黑客,愿意颠覆类型系统以获得有效的方法:
int (&array2)[5] = (int (&)[5])(*(array1 + 5));
Now array2
will be an array for all intents and purposes, and will be a sub-array of array1
, and will even be passable to that famous C++ array_size
template function. Though the best way to handle this hackery is to hide it with more hackery!
现在array2
将是一个用于所有意图和目的的数组,并且将是 的子数组array1
,甚至可以传递给那个著名的 C++array_size
模板函数。尽管处理这种黑客行为的最佳方法是用更多的黑客行为隐藏它!
#define make_sub_array(type, arr, off, len) (type (&)[len])(*(arr + off));
int (&array2)[5] = make_sub_array(int, array1, 5, 5);
Nice. Terrible by some standards, but the end result a) looks pretty neat, b) does exactly what you want, c) is functionally identical to an actual array, and d) will also have the added bonus (or mis-feature) of being an identical reference to the original, so the two change together.
好的。以某些标准来看很糟糕,但最终结果 a) 看起来很整洁,b) 完全符合您的要求,c) 在功能上与实际数组相同,并且 d) 还会有额外的好处(或错误特征)对原始的相同引用,因此两者一起更改。
UPDATE: If you prefer, a templated version (sort of):
更新:如果您愿意,模板化版本(有点):
template <typename T, size_t M>
T (&_make_sub_array(T (&orig)[M], size_t o))[]
{
return (T (&)[])(*(orig + o));
}
#define make_sub_array(type, array, n, o) (type (&)[n])_make_sub_array(array, o)
int (&array2)[5] = make_sub_array(int, array1, 5, 5);
We still have to pass the type. Since one of our arguments must be used as part the cast, we cannot cleanly (IMHO) avoid the macro. We could do this:
我们仍然需要传递类型。由于我们的参数之一必须用作演员表的一部分,我们不能干净地(恕我直言)避免使用宏。我们可以这样做:
template <typename T, size_t M, size_t N>
T (&make_sub_array(T (&orig)[M], size_t o))[N]
{
return (T (&)[N])(*(orig + o));
}
int (&array2)[5] = make_sub_array<int, 15, 5>(array1, 5);
But the goal here is to make the calling code as clean as possible, and that call is a bit hairy. The pure-macro version probably has the least overhead and is probably the cleanest to implement in this case.
但是这里的目标是使调用代码尽可能干净,而且这个调用有点麻烦。纯宏版本可能具有最少的开销,并且在这种情况下可能是最容易实现的。
回答by lhahne
For a completely different approach you could do something like.
对于完全不同的方法,您可以执行类似的操作。
vector<int> v0(array1 + 95, array1 + 100);
or
或者
vector<int> v1(array1, array1 + 100);
vector<int> v2(v1.begin() + 95, v1.end());
This would make a real copy of the elements of your vector.
这将制作矢量元素的真实副本。
回答by Emile Cormier
You can use boost::iterator_rangeto represent "slices" of arrays/containers:
您可以使用boost::iterator_range来表示数组/容器的“切片”:
#include <iostream>
#include <boost/range.hpp>
int main()
{
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// Create a "proxy" of array[5..7]
// The range implements the concept of a random sequence containter
boost::iterator_range<int*> subarray(&array[5], &array[7]+1);
// Output: 3 elements: 5 6 7
std::cout << subarray.size() << " elements: "
<< subarray[0] << " "
<< subarray[1] << " "
<< subarray[2] << "\n";
}
Note that the iterator range "knows" about the size of the sub-array. It will even do bounds checking for you. You cannot get that functionality from a simple pointer.
请注意,迭代器范围“知道”子数组的大小。它甚至会为你做边界检查。您无法从简单的指针获得该功能。
The usefulness of Boost.Range will become more apparent once you learn about STL containers and iterators.
一旦您了解了 STL 容器和迭代器,Boost.Range 的用处就会变得更加明显。
If you're into linear algebra, Boost.uBlassupports ranges and slices for its matrices and vectors.
如果您喜欢线性代数,Boost.uBlas支持矩阵和向量的范围和切片。
回答by John Knoeller
In C++ you can use an int pointer as an int array, so getting the array2 to start at item 96 in array1 is easy, but there isn't any way to give array2 a size limit, so you can do this
在 C++ 中,您可以将 int 指针用作 int 数组,因此让 array2 从 array1 中的第 96 项开始很容易,但没有任何方法可以给 array2 设置大小限制,因此您可以这样做
int array2[] = &array1[96];
int array2[] = &array1[96];
or this
或这个
int *array2 = &array1[96];
but NOT this
但不是这个
int array2[5] = &array1[96]; // this doesn't work.
On the other hand, C++ doesn't enforce array size limits anyway, so the only real loss is that you can't use sizeof to get the number of elements in array2.
另一方面,C++ 无论如何都不会强制执行数组大小限制,因此唯一真正的损失是您无法使用 sizeof 来获取 array2 中的元素数。
note: &array1[96]
is the same thing as array+96
注意: &array1[96]
是一样的东西array+96
edit: correction - int array[] = &array[96]
isn't valid, you can only use [] as a synonym for * when declaring a function parameter list.
编辑:更正 -int array[] = &array[96]
无效,在声明函数参数列表时,您只能使用 [] 作为 * 的同义词。
so this is allowed
所以这是允许的
extern int foo(int array2[]);
foo (&array1[96]);
回答by Judge Maygarden
int array1[] = {1,2,3,...99,100};
int *array2 = &array1[96];
回答by Jagannath
int arr[] = { 1, 2, 3, 4, 5};
int arr1[2];
copy(arr + 3, arr + 5, arr1);
for(int i = 0; i < 2; i++)
cout << arr1[i] << endl;
The code is not safe if the boundaries are not handled properly.
如果边界处理不当,代码是不安全的。
回答by BlueRaja - Danny Pflughoeft
You said you don't want to copy the array, but get a pointer to the last five elements. You almost had it:
你说你不想复制数组,但得到一个指向最后五个元素的指针。你几乎拥有它:
int array1[] = {1,2,3,...99,100};
int* array2 = &array1[95];