[solved] Number of elements in arrays parameters

Hi ! For more clarity, I want to remove useless parameters, but I can't get them inside of the function for unknown reason.
Can you tell me what to write in this code please ? (it doesn't work)

float array1[] = {1, 2.5, 3.1};

int key0[] = {0, 1, NULL};
int key1[] = {1, 3, 4};
int *array2[] = {key0, key1};

void setup()
{
	Serial.begin(9600);
	Serial.println("Lancement");

	TestArray(array1, array2);
}

bool TestArray(float arr1[], int *arr2[])
{
	int arr1Size = sizeof(arr1) / sizeof(float); // numbers of float in this array
	Serial.println(arr1Size);

	int arr2Size = sizeof(arr2[0]) / sizeof(int); // numbers of int (NULL included) in the first pointer of this array
	Serial.println(arr2Size);
}

void loop()
{}

Aerosmite:

int arr2Size = sizeof(arr2[0]) / sizeof(int); //

the size of a pointer (on an Uno) is 2 bytes.

Usually when passing a pointer to an array you would pass the length of the array as well, like this:

float array1[] = {1, 2.5, 3.1};

void setup() 
{
  Serial.begin(115200);
  float average = getAverage(array1, sizeof(array1)/sizeof(array1[0]));
  Serial.println(average);

}

void loop() {
  // put your main code here, to run repeatedly:

}

float getAverage(float* arry, size_t size)
{
  float sum = 0.0;
  for (int i = 0; i < size; i++)
  {
    sum += arry[i];
  }
  return sum / size;
}

There's another way: In C++, you can specify the size of an array as function parameter.

For example, a function that takes a float array with 3 elements as a parameter:

void fn(float (&array)[3]) {
  // ...
}

You could use it as follows:

float array1[] = {1, 2.5, 3.1};
fn(array1);

However, if you try an array with a different length, the compiler will complain:

float array1[] = {1, 2.5, 3.1, 4.6};
fn(array1);
error: invalid initialization of reference of type 'float (&)[3]' from expression of type 'float [4]'
 fn(array1);
          ^
note: in passing argument 1 of 'void fn(float (&)[3])'
 void fn(float (&array)[3]) {
      ^

You could solve this by overloading the function (i.e. creating a version of the function for every type of parameter you need, so a new function for every length):

void fn(float (&array)[1]) {
  // ...
}
void fn(float (&array)[2]) {
  // ...
}
void fn(float (&array)[3]) {
  // ...
}
void fn(float (&array)[4]) {
  // ...
}
// etc ...

As you can see, it would be a pain to write them all out manually. Luckily, C++ has something called function templates:

template <size_t N> void fn(float (&array)[N]) {
  // ...
}

This will define a family of functions, all with a different length N for 'array'. The compiler will automatically overload the function with any length N needed in your program.

A more extensive example:

float array1[] = {1, 2.5, 3.1};

template <size_t N> void printArray(float (&arr)[N]) {
  Serial.print("Array size: ");
  Serial.println(N);
  for (size_t i = 0; i < N; i++) {
    Serial.print('\t');
    Serial.print(arr[i]);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  while (!Serial);
  printArray(array1);
}

void loop() {}

This will print:

Array size: 3
 1.00 2.50 3.10

Note that this will only work if the length of the array is fixed, and known at compile time.
For example, this won't work:

void setup() {
  Serial.begin(115200);
  while (!Serial);
  printArray(array1);

  size_t length = random(1, 10);
  float* array2 = new float[length];
  for (size_t i = 0; i < length; i++) {
    array2[i] = 1.0 / (i + 1);
  }
  printArray(array2);
  delete[] array2;
}

This is easy to solve, though:

float array1[] = {1, 2.5, 3.1};

template <size_t N> void printArray(float (&arr)[N]) {
  printArray(arr, N);
}

void printArray(float* arr, size_t length) {
  Serial.print("Array size: ");
  Serial.println(length);
  for (size_t i = 0; i < length; i++) {
    Serial.print('\t');
    Serial.print(arr[i]);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  while (!Serial);
  printArray(array1);

  size_t length = random(1, 10);
  float* array2 = new float[length];
  for (size_t i = 0; i < length; i++) {
    array2[i] = 1.0 / (i + 1);
  }
  printArray(array2, length);
  delete[] array2;
}

void loop() {}

Note how the template function from before is now just a wrapper for the actual function.

Pieter

Thanks for your answers, I just realized how complicated this is, because function only get the pointer and nothing else.
I want to keep my code readable for my friends, so I'll just keep length parameters :wink: