在C语言中,将数组和矩阵作为指针和指向指针的指针传递给函数
给定以下代码:在C语言中,将数组和矩阵作为指针和指向指针的指针传递给函数,c,pointers,parameters,C,Pointers,Parameters,给定以下代码: void foo( int* array ) { // ... } void bar( int** matrix ) { // ... } int main( void ) { int array[ 10 ]; int matrix[ 10 ][ 10 ]; foo( array ); bar( matrix ); return 0; } 我不明白为什么我会收到这样的警告: 警告:从不兼容的指针类型传递“bar
void
foo( int* array )
{
// ...
}
void
bar( int** matrix )
{
// ...
}
int
main( void ) {
int array[ 10 ];
int matrix[ 10 ][ 10 ];
foo( array );
bar( matrix );
return 0;
}
我不明白为什么我会收到这样的警告:
警告:从不兼容的指针类型传递“bar”的参数1
虽然“foo”这个电话似乎还可以
谢谢:)您应该将bar定义为:
bar( int* matrix )
在C中,所有数组都应作为int*
(或type\u元素*
传递给其他类型)
int**
如果您的数据实际上是一个指针数组,那么就可以了<例如,code>int[*data[]这就是您在main(int-argc,char*argv[])
中得到的结果。问题是数据结构矩阵[10][10]实际上不是一个包含指向数组[10]的十个指针的表,而是一个包含100个整数的序列数组。正确的bar签名是
bar (int matrix[10][10])
如果您确实希望使用间接方式表示矩阵,并将int**matrix作为bar的参数类型,则需要以不同的方式分配它:
int *matrix[10];
int my_data[100];
int i;
for (i = 0; i < 10; i++) { matrix[i] = &(my_data[i * 10]); }
bar(matrix);
int*矩阵[10];
int my_数据[100];
int i;
对于(i=0;i<10;i++){matrix[i]=&(my_data[i*10])}而言
棒(矩阵);
现在“matrix”与int**类型匹配。“matrix”是一个由十个指针组成的数组,您可以通过指针传递它,因此在C中传递多维数组是一个棘手的问题。请参阅 要问的问题是如何使用
bar
。如果您总是知道它将被传递一个10x10数组,那么将其重写为
bar(int matrix[10][10]);
如果要处理不同尺寸的数组,则可能需要传递长度:
bar(int *matrix, int width, int height);
表示您有一个指向int的指针。这通常用于表示指向指针数组(也称为向量)的指针。对于
int matrix[10][10]
这更像是指向大小为10x10 int的单个内存段的指针。请尝试更改为:
void bar(int *matrix[])
当然,C社区并没有很好地理解这一点,只要看一下就可以看出。神奇的是,以下所有内容都是100%等效的:
void foo(int (*array)[10]);
void foo(int array[][10]);
void foo(int array[10][10]);
void foo(int array[42][10]);
区分指针和数组非常重要。数组不是指针。数组可以转换为指向其第一个元素的指针。如果有指针,则有:
--------
| ptr | -------> data
--------
---------------------------
| c1 | c2 | c3 | ... | cn |
---------------------------
但是,如果您有一个数组,则有:
--------
| ptr | -------> data
--------
---------------------------
| c1 | c2 | c3 | ... | cn |
---------------------------
使用指针,数据位于另一个星球上,但通过指针链接。数组本身就有数据。现在,多维数组只是数组的数组。数组嵌套在父数组中。因此,数组的大小为:
(sizeof(int) * 10) * 10
这是因为您有10个数组,所有数组都是10个整数的数组。现在,如果要传递该数组,它将被转换为什么?指向其第一个元素的指针。元素类型不是指针,而是数组。因此,您传递指向10个整数数组的指针:
int (*)[10] // a pointer to an int[10]
它既不是int*
数组,也不是int**
。您可能会问,为什么该数组不作为int**
传递。这是因为编译器必须知道行长度。如果执行数组[1][0]
,编译器将寻址sizeof(int)的位置*10
距离二维数组开头的字节。它在指向数组类型的指针中解码该信息
因此,您必须从上述完全等效的函数原型中选择一个。自然,最后一个是令人困惑的。如果一个参数被声明为数组,编译器只是默默地忽略在最外层维度中写入的任何数字。因此,我也不会使用最后第二个版本。最好使用第一个或第二个版本。Wh至少要记住,C没有(实数)数组参数!该参数最后将是一个指针(在本例中是指向数组的指针)
请注意,上面的多维情况与下面的退化一维情况是如何相似的。以下4个版本完全等效:
void foo(int *array);
void foo(int array[]);
void foo(int array[10]);
void foo(int array[42]);
下面是一些需要练习的代码——它包含所有可能的传递二维数组的类型和访问元素值的代码
#include <stdio.h>
#define NUMROWS 2
#define NUMCOLUMNS 5
#define FILL_ARRAY() \
*array[0] = '1'; \
(*array)[7] = '2'; \
*(array[1]) = '3'; \
*(*(array+1)+1) = '4'; \
*(array[0]+3) = '5'; \
*(*array+2) = '7'; \
array[0][1] = '6';
void multi_01( char (*array)[NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_02( char array[][NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_03( char array[NUMROWS][NUMCOLUMNS] ) { FILL_ARRAY(); }
void multi_04( char **array ) { FILL_ARRAY(); }
void multi_05( char *array[] ) { FILL_ARRAY(); }
void multi_06( char *array[NUMCOLUMNS] ) { FILL_ARRAY(); }
int main(int argc, char **argv)
{
int i;
char mystr[NUMROWS][NUMCOLUMNS] = { { 'X', 'X', 'X', 'X'}, {'X','X','X'} };
char *pmystr[sizeof(mystr)/sizeof(*mystr)];
int numcolumns = sizeof(*mystr);
int numrows = sizeof(mystr)/sizeof(*mystr);
for( i=0; i<numrows; i++ ) pmystr[i] = *(mystr+i);
multi_01( mystr ); multi_02( mystr ); multi_03( mystr );
multi_04( pmystr ); multi_05( pmystr ); multi_06( pmystr );
printf("array '%s', '%s'\n", mystr[0], mystr[1]);
getc(stdin);
return 0;
}
#包括
#定义NUMROWS 2
#定义numcolumn 5
#定义填充数组()\
*数组[0]=“1”\
(*数组)[7]=“2”\
*(数组[1])='3'\
*(*(数组+1)+1)='4'\
*(数组[0]+3)='5'\
*(*数组+2)='7'\
数组[0][1]=“6”;
void multi_01(char(*array)[NUMCOLUMNS]){FILL_array();}
void multi_02(字符数组[][NUMCOLUMNS]){FILL_数组();}
void multi_03(字符数组[NUMROWS][NUMCOLUMNS]){FILL_数组();}
void multi_04(字符**数组){FILL_数组();}
void multi_05(char*array[]){FILL_array();}
void multi_06(char*数组[NUMCOLUMNS]){FILL_数组();}
int main(int argc,字符**argv)
{
int i;
char mystr[NUMROWS][NUMCOLUMNS]={{'X','X','X','X'},{'X','X','X'};
char*pmystr[sizeof(mystr)/sizeof(*mystr)];
int numcolumns=sizeof(*mystr);
int numrows=sizeof(mystr)/sizeof(*mystr);
对于(i=0;i),问题在于数据结构矩阵[10][10]实际上不是一个包含指向数组[10]的十个指针的表,而是一个包含100个整数的序列数组这就是为什么我如此困惑的原因!虽然Mark Pim的答案完全集中在我问题的主要问题上,但我想通过将此答案设置为推荐答案,以某种方式补偿您试图在C中解释数组作为参数的所有努力。谢谢!您的答案很好。谢谢!bar的计算结果为int**matrix,而不是您的方式将通过矩阵