Can I re-describe your question like this ?
whats the difference between the function prototype 
void initArr(int i[3])
and
void initArr(int *i)
-------------------------gcc answer-------------------
no difference (maybe its a standard ?)
-------------------------the reason-------------------
gcc generates same code
-------------------------how to try-------------------
//online parser: 
https://www.bccn.net/run/

程序代码:
#include <stdio.h>
#include <stdlib.h>
//#define ARG_TYPE
#ifdef ARG_TYPE
void initArr(int i[3])
#else
void initArr(int *i)
#endif
{
    printf("sub[i] = %d\n", i[0]);
    i[0] = 100;
    printf("sub[i] = %d\n", i[0]);
}
int main(int argc, char *argv[])
{
    int i[3] = {10, 20, 30};
    
    initArr(i);
    printf("main[i] = %d\n", i[0]);
    
    system("gcc *.c -o v.out");
#ifdef ARG_TYPE
    system("objdump -d v.out > a.txt");
    system("cat a.txt");
#else
    system("objdump -d v.out > b.txt");
    system("cat b.txt");
#endif
    system("diff a.txt b.txt");
    return 0;
}
output sample:
......
<
   4004ef:
    49 c7 c0 20 07 40 00
     mov
    $0x400720,%r8
<
   4004f6:
    48 c7 c1 b0 06 40 00
     mov
    $0x4006b0,%rcx
---
>
   4004ef:
    49 c7 c0 30 07 40 00
     mov
    $0x400730,%r8
>
   4004f6:
    48 c7 c1 c0 06 40 00
     mov
    $0x4006c0,%rcx
......
So, finally you will find that nothing is different except the dynamic address