好的,我正在尝试从现有阵列中获取子阵列,我只是不确定如何做到这一点。在我的例子中,我有一个非常大的数组,但我想从数组的最后5个元素创建一个数组。
我所谈论的一个例子是:
int array1 = {1,2,3,...99,100};
int array2[5] = array1+95;
我知道这是不正确的,但我在纠正它时遇到了一些麻烦。我想在array1中获取元素96到100并将它们放入array2但我不想复制数组。我只想让array2从96元素开始,这样array1 [96]和array2 [0]将指向同一个位置。
答案 0 :(得分:18)
为此:
"such that array1[96] and array2[0] would be pointing to the same location."
你可以这样做:
int *arr2 = arr1 + 96;
assert(arr2[0] == arr1[96] == 97);
答案 1 :(得分:9)
来自C程序员的参考黑客,他们愿意破坏类型系统以使其起作用:
int (&array2)[5] = (int (&)[5])(*(array1 + 5));
现在array2
将是一个用于所有意图和目的的数组,并且将是array1
的子数组,甚至可以传递给那个着名的C ++ array_size
模板函数。虽然处理这个hackery的最好方法是隐藏它更多的hackery!
#define make_sub_array(type, arr, off, len) (type (&)[len])(*(arr + off));
int (&array2)[5] = make_sub_array(int, array1, 5, 5);
尼斯。一些标准可怕,但最终结果a)看起来非常整洁,b)完全符合你的要求,c)在功能上与实际数组完全相同,并且d)还将具有额外的奖励(或错误特征)与原作相同的参考,所以两者一起改变。
更新:如果您愿意,可以使用模板化版本(等等):
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);
我们仍然要传递这种类型。由于我们的一个参数必须用作演员的一部分,我们不能干净地(恕我直言)避免宏。我们可以这样做:
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);
但是这里的目标是使调用代码尽可能干净,并且调用有点毛茸茸。纯宏版本可能具有最小的开销,在这种情况下可能是最干净的。
答案 2 :(得分:3)
对于完全不同的方法,你可以做类似的事情。
vector<int> v0(array1 + 95, array1 + 100);
或
vector<int> v1(array1, array1 + 100);
vector<int> v2(v1.begin() + 95, v1.end());
这将成为载体元素的真实副本。
答案 3 :(得分:3)
您可以使用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";
}
请注意,迭代器范围“知道”子数组的大小。它甚至会为你检查边界。您无法通过简单的指针获得该功能。
一旦了解了STL容器和迭代器,Boost.Range的用处就会变得更加明显。
如果你是线性代数,Boost.uBlas支持其矩阵和向量的范围和切片。
答案 4 :(得分:1)
在C ++中你可以使用int指针作为int数组,所以让array2从array1中的item 96开始很容易,但是没有办法给array2一个大小限制,所以你可以这样做< / p>
<击> int array2 [] =&amp; array1 [96];
或者这个
击>
int *array2 = &array1[96];
但不是这个
int array2[5] = &array1[96]; // this doesn't work.
另一方面,C ++不会强制执行数组大小限制,因此唯一真正的损失是你不能使用sizeof来获取array2中的元素数。
注意:&array1[96]
与array+96
编辑:更正 - int array[] = &array[96]
无效,在声明功能参数列表时,只能使用[]作为*的同义词。
所以这是允许的
extern int foo(int array2[]);
foo (&array1[96]);
答案 5 :(得分:0)
你说你不想复制数组,但得到一个指向最后五个元素的指针。你几乎拥有它:
int array1[] = {1,2,3,...99,100};
int* array2 = &array1[95];
答案 6 :(得分:0)
int array1[] = {1,2,3,...99,100};
int *array2 = &array1[96];
答案 7 :(得分:0)
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;
如果边界处理不当,代码就不安全。