传递一个大小可变的多维数组

13

我正在尝试理解在C语言中将多维数组传递给函数的“最佳实践”(或者说任何实践)是什么。当然,这取决于具体应用,所以让我们考虑编写一个打印可变大小的二维数组的函数。特别地,我对如何编写下面代码中的函数printArry(__, int a, int b)很感兴趣。由于我不确定第一个参数应该是什么,因此省略了它。

void printArry(_____, int a, int b){
/* what goes here? */
}


int main(int argc, char** argv){

int a1=5;
int b1=6;
int a2=7;
int a2=8;

int arry1[a1][b1];
int arry2[a2][b2];

/* set values in arrays */

printArry(arry1, a1, b1);
printArry(arry2, a2, b2);

}

我已经在以下链接发布了跟进内容:http://stackoverflow.com/questions/34560001/passing-a-multidimensional-array-of-variable-size-without-vla - ABD
2个回答

17

最简单的方法是(适用于C99及以上)

void printArry(int a, int b, int arr[a][b]){
    /* what goes here? */
}

但是,还有其他的解决方法

void printArry(int a, int b, int arr[][b]){
    /* what goes here? */
}

或者
void printArry(int a, int b, int (*arr)[b]){
    /* what goes here? */
}

编译器将把前两个调整为第三个语法。因此,从语义上讲,所有三个都是相同的。
有一点令人困惑,这只能作为函数原型起作用。
void printArry(int a, int b, int arr[*][*]);

2
我从未知道 int arr[a][b] 可以作为参数;这个何时出现在标准中的? - abligh
@stian; 有很多种方法。但是,我建议使用这个答案中的第一种方法。 - haccks
1
我喜欢第二/第三个例子,因为只需要知道一个二维数组的宽度就可以使用它。 - Weather Vane
1
@ABD;我附上了答案链接。请阅读被采纳的答案以获取详细解释。 - haccks
1
前三个选项的语义含义完全相同,我认为在问题中涵盖这一点会对普通读者有所帮助。(前两个选项调整为int (*arr)[b])。我会选择第一个选项,因为它具有自说明性。此外,已经提议在C2X中弃用*版本。 - M.M
显示剩余11条评论

2

这并不是一个真正的答案,而是对OP评论问题的延伸评论:“好吧,你可以在不知道行数的情况下传递数组,但是你如何知道何时停止打印行?”

答案:通常情况下,如果不传递数组大小,你无法知道。看看这个一维示例,它破坏了数组大小。

#include <stdio.h>

int procarr(int array[16], int index)
{
   return array[index];
}

int main (void)
{
    int arr[16] = {0};
    printf("%d\n", procarr(arr, 100));
    return 0;
}

程序输出结果(尽管所有元素都被初始化为0):

768

这是一种未定义的行为,编译器没有警告。C语言没有提供任何数组越界保护,除了数组定义初始化器(尽管这样的初始化器可以定义数组长度)。您还需要传递数组大小,如下所示:

#include <stdio.h>

int procarr(int array[16], size_t index, size_t size)
{
    if (index < size)
        return array[index];
    return -1;                  // or other action / flag
}

int main (void)
{
    int arr[16] = {0};
    printf("%d\n", procarr(arr, 100, sizeof arr / sizeof arr[0]));
    return 0;
}

程序输出:

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接