4

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

  1. void test(char a[5][10])
  2. void test(char (*a)[10])

上面的声明对我有用,但是在查看**argv函数 main 的参数时,我想将函数更改为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));
}
4

6 回答 6

4

传递给函数的数组名称将衰减为其第一个元素的地址值,其类型将是指向该元素类型的指针。既然类型multi[0]是a char[10],那么multi就会衰减pointer to char[10]

main()在它的第二个参数中接收一个指针数组char,这就是为什么argv可以是char **argvor char *argv[]

于 2013-07-10T06:39:58.830 回答
4

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

在指向指针的情况下,行存储在任意内存位置。给定指向第一行的指针和索引,您无法找到行的位置。在这种情况下,您需要与行数一样多的指针。

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

于 2013-07-10T06:43:37.233 回答
2

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

于 2013-07-10T07:09:56.530 回答
1

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

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

printf("\na[2][1] 是: %d",*(*(a + 2)+1));

于 2013-07-10T06:44:33.470 回答
0

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

于 2013-07-10T06:45:18.293 回答
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));
}
于 2013-07-10T07:08:06.580 回答