Array Basics (sizeof)

westfw:

If you dereference a real pointer to an array, you can get the size using sizeof.

Only if it's a compile-time constant, right?
(and, are you sure? I though ((sizeof array)/sizeof(*array)) was one of those tricks for finding the number of elements in an array...)

No, its not required to be a compile time constant for arrays.

void someFunc( int n ){
  
  int arr[ n ];
  Serial.println( sizeof( arr ) / sizeof( *arr ) );
}
//...
someFunc( random( 1, 30 ) );

I think I know what people are misunderstanding here, I'll fill in a few gaps.

Arrays are not lists of values based on a type, that is what their internal representation is. Arrays are actual types too. E.g. I can create a typedef of an array.

typedef int arr_t[ 10 ];

Not only can I create variables of this type:

arr_t arr = { 1,2,3,4,5,6,7,8,9,0 };

I can use it just like every other type.

void Foo( arr_t *arrp ){
  
  Serial.println( sizeof( *arrp ) / sizeof( **arrp ) );
}
//...
Foo( &arr );

A more practical method is to use a reference to avoid dereferencing the array.

void Foo( arr_t &ref ){
  Serial.println( sizeof( ref ) / sizeof( *ref ) );
}
//...
Foo( arr );

And finally, unknown to many, you can actually return arrays using their pointer or reference.

typedef int arr_t[10];
arr_t &Foo( arr_t &ref ); //Forward dec to stop IDE moaning

arr_t arr = { 1,2,3,4,5,6,7,8,9,0 };

arr_t &Foo( arr_t &ref ){
  Serial.println( sizeof( ref ) / sizeof( *ref ) );
  return ref;
}

void setup() {

  Serial.begin( 9600 );
  arr_t &ret = Foo( arr );
}

void loop(){}

I'm writing an FAQ on this topic on my site ( unfinished ), however this is a basic run down.