What is the difference in these C function argument type? : <pre><code>void f(int **);
void g(int *[]);
void h(int *[3]);
void i(int (*)[]);
void j(int (*)[3]);
void k(int [][3]);

void f(int **a) {}
void g(int *a[]) {}
void h(int *a[3]) {}
void i(int (*a)[]) {}
void j(int (*a)[3]) {}
void k(int a[][3]) {}

int main(void) {
    int a[3] = {1,2,3};
    int b[2] = {4,5};
    int *c[2] = {a, b};
    int d[2][3] = {{1,2,3},{4,5,6}};
    f(c);
    f(d); // note: expected ‘int **’ but argument is of type ‘int (*)[3]’
    g(c);
    g(d); // note: expected ‘int **’ but argument is of type ‘int (*)[3]’
    h(c);
    h(d); // note: expected ‘int **’ but argument is of type ‘int (*)[3]’
    i(c); // note: expected ‘int (*)[]’ but argument is of type ‘int **’
    i(d);
    j(c); // note: expected ‘int (*)[3]’ but argument is of type ‘int **’
    j(d);
    k(c); // note: expected ‘int (*)[3]’ but argument is of type ‘int **’
    k(d);
    return 0;
}
</code></pre>

<p>What is the difference in these C function argument type?
There're a lot of confusing between <strong>arrays of pointers</strong> and <strong>two dimensional arrays</strong>
The comments are the GCC warning logs.</p>
