int*はアドレスを持つだけだけの変数で長さは不定
配列は言うなればint[3]型みたいなものでint3個分の大きさを持つ1つの変数
配列をsizeofすればその大きさが取れるだろう

例えば
char aho[3]{};
std::cout << &aho << std::endl;
std::cout << (&aho) + 1 << std::endl;
とすれば2回目の出力では3バイト先のアドレスが出力される
これはアドレス1つ分進める操作でchar[3]型のサイズ1つ分進めた証拠

それでこれらの違いはテンプレートにおいては重要になる
普通の処理では便宜上確保したメモリ領域も配列と表現することもあるしそれで差し支えない事も多いけどテンプレートではそうではない

VC++ではstd::begin、std::endはこうなっている(余計な修飾子は消した)
template<class _Ty, size_t _Size> _Ty *begin(_Ty (&_Array)[_Size])
{ // get beginning of array
  return (_Array);
}

template<class _Ty, size_t _Size> _Ty *end(_Ty (&_Array)[_Size])
{ // get end of array
  return (_Array + _Size);
}

2番目のテンプレート引数に注目すれば分かることだが配列型を入れると長さを取ることができる
こうすれば配列の末尾のアドレスを取る関数を作る事ができる
こういうことをやっているからアドレスを渡しても使うことはできない