在我们的一个文件中,我看到了这个功能
void match(int states[*]);
Run Code Online (Sandbox Code Playgroud)
我在C中从未见过这样的事情.有人可以解释一下括号中这个奇怪的算子是什么意思吗?
这是C99中的新语法.它仅对函数声明中的参数有效,该参数也不是定义.它表示一个未指定长度的可变长度数组; 在这种情况下,因为它处于顶层,所以(通常)完全等同于int states[]和int *states.
如果传递指向数组的指针,则此语法很有用 - 例如,如果我们有一个类似的函数:
void foo(size_t n, int a[][n])
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
..然后我们可以写一个兼容的声明,提供一个原型:
void foo(size_t n, int a[][n]);
Run Code Online (Sandbox Code Playgroud)
或作为:
void foo(size_t, int a[][*]);
Run Code Online (Sandbox Code Playgroud)
这些完全相同.
(顺便说一下,*没有操作员,只是标点符号.)
[*]表示未指定大小的C99可变长度数组,它仅在原型中有效,但仍然是完整类型(即不同于[],表示不完整的数组类型).
然而,你的例子毫无意义.一个更合理的例子是
// in header file:
void match(size_t, int *[*]);
// in source file:
void match(size_t count, int *states[count])
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
由于省略了参数名称,因此数组声明不能引用第一个参数,因此必须引入占位符.
但是,由于参数调整仍然适用,原型与之相同
void match(size_t, int **);
Run Code Online (Sandbox Code Playgroud)
并丢弃数组类型信息.
对于多维阵列的较高指数而言,情况并非如此,例如
double det(size_t rows, size_t cols, double mat[rows][cols]);
Run Code Online (Sandbox Code Playgroud)
只丢弃rows,即声明相当于
double det(size_t rows, size_t cols, double mat[][cols]);
Run Code Online (Sandbox Code Playgroud)
和
double det(size_t rows, size_t cols, double (*mat)[cols]);
Run Code Online (Sandbox Code Playgroud)
它反过来对应于以下兼容声明
double det(size_t, size_t, double [*][*]);
double det(size_t, size_t, double [][*]);
double det(size_t, size_t, double (*)[*]);
Run Code Online (Sandbox Code Playgroud)
要防止参数调整,请将指针传递给数组,即
double det(size_t rows, size_t cols, double (*mat)[rows][cols])
Run Code Online (Sandbox Code Playgroud)
然后,sizeof *mat应返回函数体内的预期值.