I have an integer array and the fifth value should always be similar to the first value. For example, if i have:
int test[] ={1,2,3,4,1}
and if I say:
test[0]= 5
The array should look like: 5 2 3 4 5
.
Is there some way to do this? I tried with pointers, but couldn't get a good result.
CodePudding user response:
Test it on GodBolt
Using actual C syntax instead of C:
#include <array>
#include <iostream>
void print_list(std::array<int*, 5> const& list){
for( auto const& item : list ){
std::cout << *item << "\t";
}
std::cout << "\n";
}
int main(){
std::array<int, 4> n = {1, 2, 3, 4};
std::array<int*, 5> list = {&n[0], &n[1], &n[2], &n[3], &n[0]};
print_list(list);
*list[0] = 3;
print_list(list);
}
CodePudding user response:
Not possible with integers but pointers would do the trick, see here: https://www.tutorialspoint.com/cplusplus/cpp_array_of_pointers.htm
Something like:
int *sharedNumber = new int(1);
int* ptr[] = {sharedNumber, new int(2), new int(3), new int(4), sharedNumber};
cout<<"values are "<<*ptr[0]<<" "<<*ptr[4]<<"\n";
*sharedNumber = 5;
cout<<"values are "<<*ptr[0]<<" "<<*ptr[4]<<"\n";
Will show 'value is 1' and 'value is 5' for ptr[1] and ptr[4] - just make sure to delete initialised memory to avoid memory leaks.
CodePudding user response:
There is currently no way of doing what you want with the syntax you're providing. Your options, which would (minimally) alter your code are:
- Manually setting two elements to the same value (see the comments below your question);
- Writing a function for mutating elements that automatically synchronizes the first and fifth elements;
- Storing an array of pointers (which seems to be your attempt);
- Sharing state between elements of the array so that affecting one element would also change other elements, and that way "synchronizing" their values;
- Wrapping your array into a class that manages that array.
It should seem obvious which solutions are, most likely, overkill.
Here is a very simple simple implementation of the second option:
void setElement(int* array, size_t index, int value)
{
array[index] = value;
if (index == 0)
array[4] = value;
if (index == 4)
array[0] = value;
}
Keep in mind that using std::array
, std::vector
or iterators would probably be a better choice than C-style arrays and raw pointers.
CodePudding user response:
There's a way to achieve this effect for a custom wrapper type, but not for arrays:
Just implement a custom []
operator:
template<class ElementType, size_t arraySize>
class MyArray
{
public:
using value_type = ElementType;
constexpr MyArray() = default;
constexpr MyArray(std::initializer_list<ElementType> arr)
{
std::copy_n(arr.begin(), (std::min)(arraySize, arr.size()), m_data);
}
constexpr size_t size() const
{
return arraySize;
}
constexpr ElementType& operator[](size_t index)
{
return m_data[index % arraySize];
}
constexpr ElementType const& operator[](size_t index) const
{
return m_data[index % arraySize];
}
private:
ElementType m_data[arraySize];
};
int main()
{
MyArray<int, 4> a = { 1, 2, 3, 4 };
std::cout << a[4] << '\n';
a[0] = 5;
std::cout << a[4] << '\n';
}
Note that this just "wraps around"; not only can you access the first element using index 4
, but for every index passed the remainder of the division by the array size is used as index. The second element of MyArray<int, 4>
could be accessed using indices 1, 5, 9, 4449, ect.