我正在学习将2D数组传递给C中的函数,并了解到我可以在函数中接收2D数组,如下所示:
void test(char a[5][10])
void test(char (*a)[10])
以上声明对我有用,但是查看函数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));
}
答案 0 :(得分:4)
传递给函数时的数组名称将衰减为其第一个元素的地址值,其类型将是指向该元素类型的指针。由于multi[0]
的类型为char[10]
,因此multi
会衰减pointer to char[10]
。
main()
在其第二个参数中收到指向char
的指针数组,这就是argv
可以是char **argv
或char *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));
}