У каждой переменной есть адресс в памяти (обычное натуральное число, порядковый номер какого-нибудь байта). Когда создаёте массив, его элементы (по сути, те же переменные) рассполагаются в памяти по-порядку.
Если вы будете передавать массив по значению, вам придётся передавать функции значение каждого элемента, а их могут быть сотни и тысячи. По этому, вы можете сказать адрес первого элемента, и их количество. Зная, что остальные элементы будут рассполагаться сразу за первым, функция сможет получить доступ ко всем остальным элементам.
Уточните, если что-то непонятно, или если есть вопросы по синтаксису.
Upd.// Функция, которая принимает массив.
void foo(int* arr, size_t n)
{
for (size_t i = 0; i < n; ++i)
cout << arr[i] << ' ';
}
// Функция, которая возвращает массив.
int* bar(size_t n)
{
// Массив должен быть выделен динамически, иначе
// он перестанет существовать после завершения этой функции.
int* arr = new int[n];
for (size_t i = 0; i < n; ++i)
cin >> arr[i];
return arr;
}
Обратите внимание, что если функция возвращает указатель на массив, последний должен быть выделен динамически. Иначе массив будет уничтожен при завершении функции, вы просто получите некорректный указатель и
undefined behaviour.
P.S. Не забывайте удалять динамически выделенные массивы (
delete[] arr;
), после того, как они станут больше не нужны.