Using only part of the array

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 should get a different array range. Is there a way to send an array with elements from 0 to 23 for one function, elements 24 to 38 for another and elements 39 to 64 for the third function.

In some languages ​​(e.g. python, I think) you can do something like this:

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

However, I use C ++, and I do not know how to do this in C ++.

Does anyone know how to do this?

SomeFunction (); is a function from the API, so I cannot change the arguments that it takes.

+6
source share
6 answers

The python example creates copies. If this is suitable for your use case, you can do something like this (I am replacing your vanilla arrays for 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 looks like you cannot use std :: vector, because somefunction () has a signature that you cannot change. Fortunately, you can only do this kind of gymnastics manually by copying parts of the array, as shown below:

 #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 displays:

 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 
+4
source

If you write functions to work with a pair of iterators ahead, and not with an array, you can simply pass it like this:

 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 allows you to use functions on parts of vectors, queues, or other STL containers.

+12
source

Your function will need some way to determine the size of the array anyway. I suggest you make the function start and end iterators in the style of standard library algorithms, for example:

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

Then you can call it with your array as follows:

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

There are two ways to do this:

 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 rather the C path, the second is more C ++. Please note that with the second method, the range [start, end) - end not included in the range, as you can see a lot in C ++.


EDIT:. You edited your post to mention that you are using glTexCoordPointer() . In this case, pass the beginning to the array on glTexCoordPointer() , which will be either myArray , myArray + 24 , or myArray + 39 .

The size of the array must still be known, and it is passed to functions such as glDrawArrays or glDrawElements() , after which reading from the array will begin. If you used glDrawArrays() , the length of the array is passed as the second argument. So your code might look something like this:

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

There is no verification of the range of upper bounds, so you must take care of this yourself. But you can pass & my_array [0] to one function and & my_array [24] to another. Perhaps add the len parameter to your function to take care of the upper range.

0
source

You can reorganize your functions to use "iterators": a pointer to the beginning and to the end of the range of arrays you are 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:

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

...

0
source

Source: https://habr.com/ru/post/902972/


All Articles