在C中传递2D数组,如main的argv

时间:2013-07-10 06:33:54

标签: c pointers

我正在学习将2D数组传递给C中的函数,并了解到我可以在函数中接收2D数组,如下所示:

  1. void test(char a[5][10])
  2. void test(char (*a)[10])
  3. 以上声明对我有用,但是查看函数main的**argv参数我想到将我的函数更改为void test(char **a)。但这不能正常工作。我不懂为什么。请解释一下。

    这是我的代码

    #include<stdio.h>
    
    int main(int argc, char **argv){
        char multi[5][10] = {
                             {'0','0','2','3','4','5','6','7','1','9'},
                             {'a','b','c','d','e','f','g','h','i','j'},
                             {'A','B','C','D','E','F','G','H','I','J'},
                             {'9','8','7','6','5','4','3','2','1','0'}, 
                             {'J','I','H','G','F','E','D','C','B','A'}
                            };
        test(multi);
        return 0;
    }
    
    void test(char (*a)[10]) // void test(char **a) does not work
    {
        printf("\n a[2][1] is: %d",*(*(a + 2)+1));
    }
    

6 个答案:

答案 0 :(得分:4)

传递给函数时的数组名称将衰减为其第一个元素的地址值,其类型将是指向该元素类型的指针。由于multi[0]的类型为char[10],因此multi会衰减pointer to char[10]

main()在其第二个参数中收到指向char的指针数组,这就是argv可以是char **argvchar *argv[]的原因。

答案 1 :(得分:4)

对于多维数组,行存储在连续的内存位置。这就是为什么我们需要传递列数,即计算要跳转到特定行的项目数。

在指向指针的情况下,行存储在任意内存位置。给定指向第一行和索引的指针,您找不到行的位置。在这种情况下,您需要尽可能多的指针。

简而言之,函数参数的两个版本假设不同的内存布局,因此它们是不兼容的。

答案 2 :(得分:2)

C中的数组本质上是一维的。传递多维数组时,您应该将每个维度大小(第一个除外)作为常量整数传递。并且数组作为指针传递,而不是数组。这是一个替代方案:传递一维或多维指针,以及尺寸大小。例如: void test(char * a,int row,int column); 并且索引是:column * i + j; 要么: void test(char ** a,int row,int column);

答案 3 :(得分:1)

char(* a)[10]是指向字符数组的指针。操作(a + 1)将a的值增加10个字节。

char ** a是一个双指针。在这种情况下,操作(a + 1)将a的值增加4个字节。因此,以下陈述将导致错误的行为。

  

printf(“\ n a [2] [1] is:%d”,*(*(a + 2)+1));

答案 4 :(得分:0)

这不是一个正式的解释,但这就是我理解的方式:数组实际上是在内存中线性存储的。例如,您定义一个10x10数组并执行b=a[4][5],系统将在内存中查找4*10+5=45元素。这就是为什么你不能传递**a并将其作为2D数组访问的原因。它是没有维度信息的指针。使用a[4][5],程序将找到4*(number of columns)+5元素。由于它不知道连续有多少元素,因此无法做到这一点。

答案 5 :(得分:0)

你可以随时做这样的事情

#include<stdio.h>
#include<stdlib.h>
void test(char **a);
int main(int argc, char **argv){
    char **multi = (char**) malloc (5*sizeof(char*));
    char a[5][10] = {{'0','0','2','3','4','5','6','7','1','9'}, {'a','b','c','d','e','f','g','h','i','j'}, {'A','B','C','D','E','F','G','H','I','J'}, {'9','8','7','6','5','4','3','2','1','0'}, {'J','I','H','G','F','E','D','C','B','A'}};
    int i,j;
    for(i=0;i<5;i++)
    {
        multi[i] = (char*) malloc (10*sizeof(char));
    }
    for(i = 0;i<5;i++) 
    {
        for(j = 0; j < 10 ;j++)
        {
            multi[i][j] = a[i][j];

        }
    }
    test(multi);
    return 0;
}

void test(char **a) // void test(char **a) does not work
{
    printf("\n a[2][1] is: %c\n",*(*(a + 2)+1));
}