只使用数组的一部分

using only part of an array

本文关键字:一部分 数组      更新时间:2023-10-16

我有一个动态分配的float数组,我需要将这个数组作为参数传递给三个不同的函数,但每个函数需要获得数组的不同范围。有没有办法可以把元素0到23的数组发送给一个函数,元素24到38发送给另一个函数,元素39到64发送给第三个函数?

在一些语言中(比如python)你可以这样做:

somefunction(my_array[0:23]);
somefunction(my_array[24:38]);
somefunction(my_array[39:64]);

然而,我正在使用c++,我不知道在c++中有任何方法可以做到这一点。

有人知道怎么做吗?

somefunction ();是一个来自API的函数,所以我不能修改它接受的参数。

如果您编写的函数要操作一对正向迭代器而不是数组,则可以像这样传递它:

somefunction1(my_array, my_array + 24);
somefunciton2(my_array + 24, my_array + 39);
somefunction3(my_array + 39, my_array + 65);

指针是前向迭代器,这将允许函数在vector、队列或其他STL容器的部分上使用。

python示例正在复制。如果这适合您的用例,您可以这样做(我将把您的普通数组换成std::vector):

#include <iostream>
#include <vector>
void somefunction(std::vector<int> v) {
    std::cout << "vector has " << v.size() << " elements,"
        << " first value is " << *v.begin() << ","
        << " last value is " << *(v.end()-1) << std::endl;
}
int main() {
    std::vector<int> a;
    for (int i=0; i<65; i++) {
        a.push_back(i);
    }
    somefunction(std::vector<int>(a.begin(),a.begin()+23));
    somefunction(std::vector<int>(a.begin()+24,a.begin()+38));
    somefunction(std::vector<int>(a.begin()+39,a.begin()+65));
}
输出:

vector has 23 elements, first value is 0, last value is 22
vector has 15 elements, first value is 23, last value is 37
vector has 27 elements, first value is 38, last value is 64

但是听起来你不能使用std::vector,因为somefunction()有一个你不能改变的签名。幸运的是,您可以做类似的操作,只需手动复制数组的部分,如下所示:

#include <iostream>
#include <string.h>
void somefunction(int v[], int len) {
    std::cout << "vector has " << len << " elements,"
        << " first value is " << v[0] << ","
        << " last value is " << v[len-1] << std::endl;
}
int main() {
    int a[65];
    for (int i=0; i<65; i++) {
        a[i] = i;
    }
    int b[23];
    memcpy(b, a, 23*sizeof(int));
    somefunction(b, 23);
    int c[15];
    memcpy(c, a+23, 15*sizeof(int));
    somefunction(c, 15);
    int d[27];
    memcpy(d, a+38, 27*sizeof(int));
    somefunction(d, 27);
}

再次输出:

vector has 23 elements, first value is 0, last value is 22
vector has 15 elements, first value is 23, last value is 37
vector has 27 elements, first value is 38, last value is 64

无论如何,您的函数将需要某种方法来确定数组的大小。我建议你让函数接受begin和end迭代器,采用标准库算法的风格,如下所示:

template<typename I>
void somefunction(I begin, I end);

然后,你可以像这样用数组调用它:

somefunction(my_array, my_array + 24);
somefunction(my_array + 24, my_array + 39);
somefunction(my_array + 39, my_array + 65);

有两种方法:

void useArray(int array[], size_t len) { ... }
...
useArray(myArray, 24);
useArray(&myArray[24], 15);
useArray(&myArray[39], 26);

void useArray(int *start, int *end) { ... }
...
useArray(myArray, myArray + 24);
useArray(myArray + 24, myArray + 39);
useArray(myArray + 39, myArray + 65);

第一个更像C的方式,第二个更像c++的方式。请注意,对于第二种方式,范围是[start, end) - end不包括在范围内,这在c++中很常见。


编辑:你编辑了你的帖子,提到你正在使用glTexCoordPointer()。在这种情况下,将数组的开头传递给glTexCoordPointer(),它将是myArray, myArray + 24myArray + 39

数组的大小仍然是已知的,并被传递给glDrawArraysglDrawElements()等函数,然后它们将开始从数组中读取。如果使用glDrawArrays(),则数组的长度作为第二个参数传递。因此你的代码可以像这样:

glTexCoordPointer(..., ..., ..., my_array);
...
glDrawArrays(..., 0, 24);
glTexCoordPointer(..., ..., ..., my_array + 24);
...
glDrawArrays(..., 0, 15);
glTexCoordPointer(..., ..., ..., my_array + 39);
...
glDrawArrays(..., 0, 26);

没有上界范围检查,所以你必须自己处理。但是您可以将&my_array[0]传递给一个函数,将&my_array[24]传递给另一个函数。也许可以在你的函数中添加一个len参数来处理上限。

你可以重构你的函数,使用'迭代器':指向你感兴趣的数组范围的开始和结束的指针:

 void somefunction( int* begin, int* end ) {
    for( int* i=begin; i != end; ++i ) {
       //stuff with *i
    }
 }

 // usage:
 somefunction( my_array+0, my_array+23 );
 somefunction( my_array+24, my_array+38 );
 somefunction( my_array+39, my_array+64 );
额外提示:如果你将函数作为模板,你也可以将它与其他迭代器一起使用:
 template<typename T>
 void somefunction( T begin, T end ) {
    for( T i=begin; i != end; ++i ) {
       //stuff with *i
    }
 }
 vector<int> values(100);
 somefunction( values.begin(), values.end() );
 somefunction( values.rbegin(), values.rend() );

我会返回或做一些像std::pair<pointer_type, pointer_type>的东西,其中包含{Begin_Pointer, End_Pointer}所以,让我们如果我们需要切片一个原始数组(在C/c++土地只是一个指针)与特定的部分/块。我将返回,取

pointer_type element_begin = raw_array+begin;
pointer_type element_end = raw_array+end;
std::pair<pointer_type, pointer_type> = std::make_pair(element_begin, element_end);

我将有一个方便的函数,我给这些beginend非负值它将返回我一个std::pair