将多维数组传递给函数C.

时间:2011-01-20 01:47:07

标签: c multidimensional-array

我在将多维数组传递给C中的函数时遇到问题。在typedef和参数应该是什么。

目前,我的函数def看起来像这样:

int foo(char *a, char b[][7], int first_dimension_of_array);

我声明一个这样的数组:

char multi_D_array[20][7];

当我尝试这样调用函数时:

foo(d, multi_D_array, 20);

我收到警告,该函数的第二个参数来自不兼容的指针类型。我尝试了很多我在网上看过的变种,但仍然不能正确。此外,当使用GDB时,我发现只传递了2D数组的第一个数组。非常感谢对我所做错误的反馈。

6 个答案:

答案 0 :(得分:5)

大警告:我通常不会这样处理多维数组。

我试过这只是为了检查,但是这个:

#include <stdio.h>

int foo(char b[][7])
{
    printf("%d\n", b[3][4]);
    return 0;
}

int main(int argc, char** argv)
{
    char multi_d_arr[20][7];
    multi_d_arr[3][4] = 42;
    foo(multi_d_arr);
    return 0;
}

使用gcc -Wall编译并运行,没有任何问题。老实说,我不确定如何将第二个参数视为不兼容的指针类型。工作正常。

然而,既然你问,我将如何处理2-D阵列?更好的方法是使用如下指针:

char** array2d = malloc((MAX_i+1)*sizeof(char*));
for ( i = 0; i < (MAX_i+1); i++ )
{
    array2d[i] = malloc((MAX_j+1)*sizeof(char));
}

现在,为了清楚起见,您可以访问的最大元素是array2d[MAX_i][MAX_j]

完成后不要忘记反转过程:

for ( i = 0; i < (MAX_i+1); i++ )
{
    free(array2d[i]);
}
free(array2d);

现在,使用此方法,下标符号仍然有效,因此array2d[x][y]仍然可以访问正确的值。从字面上讲,array2d是一个指针数组,每个array2d[i]也是如此。

为什么这是一种更好的方法?好吧,如果您愿意,可以使用可变大小的子阵列。您所要做的就是更改for循环。这种技术通常用于字符串数组,特别是在应用程序的int main(int argc, char** argv)签名中。 argv是一个可变长度字符串数组的数组。使用strlen()确定其长度。

你可以传递这个吗?当然。你刚开始接受它的主要功能,但你也可以写下你的功能签名:

int foo(char** ar2d, const unsigned int size);

并称之为:

char** somearray;
/* initialisation of the above */

foo(ar2d, thesizeofar2d);

/* when done, free somearray appropriately */

为了清楚起见,包含大小参数的方法(如const unsigned int size)是非常好的做法,你应该坚持下去。

答案 1 :(得分:1)

你在问题​​中给出的声明和函数调用是完全正确的C,并且没有用gcc发出警告。

您确定已完全复制有问题的代码吗?

答案 2 :(得分:0)

您的代码对我有用吗?这是我的测试代码:http://codepad.org/wSppLiwl

答案 3 :(得分:0)

嗯,根据定义它是不兼容的。

char[20][7]char[][7]

不同

只是摆脱警告。

它没有传递“只有2D数组的第一个数组”,它只传递一个指向数组的指针(指向第一个元素的指针,或指向数组的开头)。 你只能看到GDB中的前7个元素,因为根据函数内部的数组类型,GDB只知道7个元素。

答案 4 :(得分:0)

从C99开始,您可以使用可变长度数组并执行以下操作。基本上,维度数组提供的参数用于声明数组大小。这很可能是现代编译器的最佳方法。

#include <stdio.h>

int foo(char *a, int fdim, char b[fdim][7]){

    printf("b[19][6] = %d\n", b[19][6]);
    return 0;
}

int main(){
    char d[10];
    char multi_D_array[20][7];
    int x, y;

    for (x = 0 ; x < 7 ; ++x){
        for (y=0 ; y < 20 ; ++y){
            multi_D_array[y][x] = y + x;
        }
    }
    foo(d, 20, multi_D_array);
}

即使它也适用于C ++,您也可以通过阅读我的答案therethere(以及其他人的答案)来更好地理解C数组。

答案 5 :(得分:-2)

底线是C / C ++不能很好地处理多维数组。大多数情况下,它更容易成为一维数组并自行进行行列寻址。