Ну, в плюсах массивы не передаются по значению. Всегда передается указатель на массив, будь то массив или даже матрица. А если точнее, то указатель на первый элемент. Это наследие Си, где массивы тесно связанны с указателями. Помимо прочего благодаря этой особенности лишний раз не выделяется память в стеке - при передаче аргументов.
void anyFunc(int myArray[]) в таком случае просто удобный синтаксис что бы показать, что передается именно указатель на массив, void anyFunc(int *myArray) тоже самое.
Можно, как рекомендует в таких случаях Страуструп определить структуру хранящую указатель на массив и его размер и принимать ее в функции.
struct Arr{
int *arrPtr;
int Size;
}
void print_array(const Arr &arr){ ... }
И вызов вашей функции сведется к такому действию:
print_array( { my_array, sizeof(my_array) / sizeof(int) } );
Но лучше всего использовать std::vector везде где нет ограничений по памяти.