为何无法声明int n[][]却能将int (*n)[]作为参数声明?
咱们先从C23标准的明确规定说起,先看这两条核心规则:
A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation...
——C23标准 6.7.7.4 #7
还有一条关于数组元素类型的硬性要求:
...The element type shall not be an incomplete or function type...
——C23标准 6.7.7.3 #1
先唠唠为啥int n[][]过不了编译。当你把它作为函数参数声明时,按照第一条规则,数组类型的参数会被自动调整成对应的指针类型。那int n[][]本质上是“元素类型为int[]的数组”,调整后本应变成指向int[]的指针,但问题出在:这里的元素类型int[]是个不完整类型——它没指定数组大小,编译器根本没法确定它的内存布局。再结合第二条规则,数组的元素类型绝对不能是不完整类型,这种声明直接违反了标准,自然会被编译器拒绝。
那int (*n)[]为啥又合法呢?因为这玩意儿本身就是个指针类型,不是数组类型,所以不会触发参数的数组-指针调整规则。它的含义是“指向int数组的指针”,虽然它指向的int[]是不完整类型,但C标准允许声明指向不完整类型的指针——毕竟指针本身的大小是固定的(比如32位系统占4字节,64位系统占8字节),编译器完全能处理这种指针作为参数的情况。后续你在函数里给这个指针赋值一个指向完整数组的地址(比如int arr[5]; n = &arr;),编译器就能正常工作了。
内容来源于stack exchange

