C++ 只使用数组的一部分

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8363325/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:26:31  来源:igfitidea点击:

using only part of an array

c++arrays

提问by PgrAm

I have a dynamically allocated array of float and I need to pass this array as an argument to three different functions but each function need to get a different range of the array. Is there some way I can send the array with elements 0 to 23 to one function, elements 24 to 38 to another, and elements 39 to 64 to a third function.

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

In some languages(like python I think) you can do something like this:

在某些语言中(如我认为的 python),您可以执行以下操作:

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

However I am using c++ and I am not aware of any way to do this in c++.

但是我使用的是 c++,我不知道在 c++ 中有什么方法可以做到这一点。

Does anybody know how to do this?

有人知道怎么做这个吗?

somefunction(); is a function from an API so I can not modify the arguments it takes.

一些功能();是来自 API 的函数,因此我无法修改它所采用的参数。

采纳答案by Al P.

The python example is making copies. If that's okay for your use case, you could do something like this (I'm swapping out your vanilla arrays for std::vector):

python 示例正在制作副本。如果这对您的用例没问题,您可以执行以下操作(我正在将您的 vanilla 数组换成 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));
}

which outputs:

输出:

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

But it sounds like you can't use std::vector, because somefunction() has a signature you can't change. Luckily, you can do similar gymnastics just manually copying parts of the array, as below:

但听起来你不能使用 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);
}

which again outputs:

再次输出:

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

回答by Harper Shelby

If you write the functions to operate on a pair of forward iterators rather than an array, you could just pass it like so:

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

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

Pointers are forward iterators, and this would allow the functions to be used over parts of vectors, queues, or other STL containers as well.

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

回答by Benjamin Lindley

Your function is going to need some way to determine the size of the array anyway. I suggest you make the function take begin and end iterators, in the style of the standard library algorithms, like so:

无论如何,您的函数将需要某种方式来确定数组的大小。我建议您按照标准库算法的风格使函数采用开始和结束迭代器,如下所示:

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

Then, you can call it with your array like this:

然后,您可以像这样使用您的数组调用它:

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

回答by AusCBloke

There are two ways you could do it:

有两种方法可以做到:

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

OR

或者

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

The first is more of a C way, the second a more C++ way. Note that with the second way, the range is [start, end)- endisn't included in the range as you see a lot in C++.

第一个更像是 C 方式,第二个更像是 C++ 方式。请注意,使用第二种方式,范围是[start, end)-end不包括在范围内,正如您在 C++ 中看到的那样。


EDIT:You edited your post to mention that you're using glTexCoordPointer(). In that case pass the start of the array to glTexCoordPointer(), which will be either myArray, myArray + 24or myArray + 39.


编辑:您编辑了您的帖子以提及您正在使用glTexCoordPointer(). 在这种情况下,将数组的开头传递给glTexCoordPointer(),即myArray,myArray + 24myArray + 39

The size of the array still has to be known though, and is passed to functions such as glDrawArraysor glDrawElements(), which will then start reading from the array. If you were using glDrawArrays(), the length of the array is passed as the second argument. Therefore your code could be something like:

尽管如此,数组的大小仍然必须知道,并传递给诸如glDrawArraysor 之类的函数glDrawElements(),然后它将开始从数组中读取。如果您使用的glDrawArrays()是 ,则数组的长度将作为第二个参数传递。因此,您的代码可能类似于:

glTexCoordPointer(..., ..., ..., my_array);
...
glDrawArrays(..., 0, 24);

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

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

回答by xtofl

You could refactor your functions to use 'iterators': a pointer to the begin and to the end of the array-range you're interested in:

您可以重构您的函数以使用“迭代器”:指向您感兴趣的数组范围的开头和结尾的指针:

 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 );

Bonus points: if you make your function a template, you can use it with other iterators too:

加分项:如果您将函数设为模板,您也可以将其与其他迭代器一起使用:

 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() );

...

...

回答by TJD

There is no upper bound range checking, so you have to take care of that yourself. But you can pass &my_array[0] to one function, and &my_array[24] to another. Maybe add a len parameter to your function to take care of upper range.

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