使用新型函数声明引用尚未提及的函数参数

时间:2019-03-27 23:55:06

标签: c c99 variable-length-array

被迫将可变长度数组功能用于打印方阵的辅助函数,我对其定义如下:

void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
    /* Print the matrix here. */
    ...

好消息是,代码可以正常工作并且其参数按照我希望的顺序排列。

坏消息是,我不得不使用“旧式”函数声明语法来引用dim声明中尚未声明的参数M,显然被认为是obsoletedangerous

是否有一种简单的方法可以在不更改参数顺序的情况下对“新样式”函数进行声明? (如果不是,那么在这种特殊情况下是否可以接受使用旧式语法?)

2 个答案:

答案 0 :(得分:2)

在便携式(标准)C中,您无法执行显示的操作。您必须在矩阵之前指定尺寸。问题中的原始代码为:

void print_matrix(M, dim)
     unsigned dim;
     int (*M)[dim][dim];
{

并且不能直接翻译-它需要这样的原型,其尺寸在矩阵之前:

void print_matrix(unsigned dim, int (*M)[dim][dim]);

这使您可以使用3D数组调用该函数。或者,使用问题中的修订符号,您可以打印2D数组:

void print_matrix(unsigned dim, int M[dim][dim]);

GCC提供了extension来协助您。引用手册:

  

如果要先传递数组,然后再传递长度,则可以在参数列表中使用前向声明(另一个GNU扩展名)。

struct entry
tester (int len; char data[len][len], int len)
{
  /* … */
}
     

您可以在参数列表中写入任意数量的此类参数前向声明。它们可以用逗号或分号分隔,但最后一个必须以分号结尾,其后是“真实”参数声明。每个前向声明必须与参数名称和数据类型中的“真实”声明匹配。 ISO C99不支持参数转发声明。

答案 1 :(得分:0)

以原型开头的旧式声明在语法上很难看,但没有新式声明那么危险。

void print_matrix(int M[*][*], unsigned dim);
void print_matrix(M, dim)
     unsigned dim;
     int M[dim][dim];
{
  ...
}

该标准的作者认识到旧式声明是完成任务的一种有效,有用且足够的方法,因此决定编写允许新式声明使用的规则会太繁琐,因此他们没有不想打扰。因此,原型和旧式声明的组合是获得适当语义的唯一方法。