Array 2D = Addressing one element

Could someone explain how you enter a change into one complete row of a 2D array

The enclosed program will not compile


int Numbers[3][13] = 
          {
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF},    //1
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF},    //2
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF}     //3 
          };

void ChangeFirstNumber()
 {
 Numbers[0][13] ={0x1101,0x1101,0x1101,0x1212,0x1111,0x1111,0x1111,0x0000,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF};
 }

void setup(void)
{
  Serial.begin(115200);
  ChangeFirstNumber();
}

void loop(void)
{
  
}

The compiler error message will tell you what is wrong with that code. Read it carefully.

To update a row in an array, store the new data in a separate array, and (in one possible approach) copy them in, one element at a time, using a loop.

Hint: post error messages as well as code.

The error message is
"cannot convert '' to 'int' in assignment"

All the examples of 2D arrays show that the whole array can be written as a series of rows, comma delimitating the variables as per the setting up of the initial array above
The only way I can find to place a new set in would be
Numbers[0][0] = 0x01101; Numbers[0][1] = 0x1101 etc
This is just not an elegant solution, nor does it fit the original method.. So why is this,

This also provides the same error, attempting to 'charge ' a total 2D array that is predefined:`

int Numbers[3][13];


void ChangeTheArray()
 {
Numbers[3][13] = 
          {
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF},    //1
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF},    //2
          {0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF,0x1FFF}     //3 
          };
 }

void setup(void)
{
  Serial.begin(115200);
  ChangeTheArray
}

void loop(void)
{
  
}

then use std::array

either a loop or a memcpy should do the job.

int Numbers[3][13] =
{
  {0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF}, //1
  {0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF}, //2
  {0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF} //3
};

void ChangeFirstNumber()
{
  int newData[] {0x1101, 0x1101, 0x1101, 0x1212, 0x1111, 0x1111, 0x1111, 0x0000, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF};
  const size_t length = sizeof(newData);
  //dest, source, bytes
  memcpy(Numbers[0], newData, length);

}

void test(int index)
{
  const size_t count = sizeof(Numbers[0]) / sizeof(Numbers[0][0]);
  for (size_t i = 0; i < count; i++)
  {
    Serial.print(" 0x"); Serial.print(Numbers[index][i], HEX);
  }
  Serial.println();
}

void setup(void)
{
  Serial.begin(115200);
  test(0);
  ChangeFirstNumber();
  test(0);
}

void loop(void)
{

}

will give

 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF
 0x1101 0x1101 0x1101 0x1212 0x1111 0x1111 0x1111 0x0 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF

This would be a bit more memory efficient if you never intend to change the data in newData. Normally the compiler would create the newData array in RAM when the ChangeFirstNumber function is called, declaring it as const and specifying PROGMEM leaves newData in program memory and memcpy_P copies directly from there without needing the intervening RAM copy.

I prefer using sizeof(Numbers[0]) for the copy instead of sizeof(newData), because a mistake with an incorrectly sized newData could overwrite whatever is stored after Numbers

void ChangeFirstNumber()
{
  static const int newData[] PROGMEM = {0x1101, 0x1101, 0x1101, 0x1212, 0x1111, 0x1111, 0x1111, 0x0000, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF, 0x1FFF};
  //dest, source, bytes
  memcpy_P(Numbers[0], newData, sizeof(Numbers[0]));
}

I think it should just be a demo for "how you enter a change into one complete row".
Assumpiton: he has his values in SRAM.

Anyhow. The OP can pick what fits best for him.

well this problem will occure vice versa. If the source is shorter then number of bytes it will also get awfully wrong...

void ChangeFirstNumber() 
{
  static const int newData[] PROGMEM = {0x1101, 0x1101}; // wrong - wrong - wrong
  //dest, source, bytes
  memcpy_P(Numbers[0], newData, sizeof(Numbers[0]));
}
0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF 0x1FFF
 0x1101 0x1101 0x300 0x2411 0xFFFFBE1F 0xFFFFEFCF 0xFFFFE0D8 0xFFFFBFDE 0xFFFFBFCD 0xFFFFE011 0xFFFFE0A0 0xFFFFE0B1 0xFFFFE7EC

garbage in - garbage out :wink:

That is incorrect. The examples show that the array can be initialized that way. Initialization is different than assignment.

Thank you all for your input