Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不兼容的参数类型?_C_Arrays_Function - Fatal编程技术网

C 不兼容的参数类型?

C 不兼容的参数类型?,c,arrays,function,C,Arrays,Function,我想使用另一个函数来打印数组的内容。 当我运行代码时,我得到“IntelliSense:类型为“int(*)[3][3]”的参数与类型为“int*(*)[3]”的参数不兼容 这是我的职责: void display(int *p[N_ROWS][N_COLS]) { int i, j; for (i = 0; i < N_ROWS; i++) { for (j = 0; j <N _COLS; j++) { printf("%i

我想使用另一个函数来打印数组的内容。 当我运行代码时,我得到“IntelliSense:类型为“int(*)[3][3]”的参数与类型为“int*(*)[3]”的参数不兼容

这是我的职责:

void display(int *p[N_ROWS][N_COLS]) {
    int i, j;
    for (i = 0; i < N_ROWS; i++) {
        for (j = 0; j <N _COLS; j++) {
            printf("%i", p[i][j]);
        }
    }
}
我的两个参数不是都是
int(*)[3][3]
类型,还是我遗漏了什么

在对您的问题的评论中已经解释了其中的大部分内容

您对
显示的定义

void display(int*p[N_ROWS][N_COLS])
{
int Array [N_ROWS][N_COLS] = { {1,2,3},{4,5,6},{7,8,9} };
display(&Array);
这表示
p
将是指向
int
的指针的数组
N行

调用
显示时

void display(int*p[N_ROWS][N_COLS])
{
int Array [N_ROWS][N_COLS] = { {1,2,3},{4,5,6},{7,8,9} };
display(&Array);
您正在传入
数组的地址
,因此它是指向
int
的数组
N行
的指针

要使
显示的定义与您调用它的方式匹配,请执行以下操作:

void display(int (*p)[N_ROWS][N_COLS])
{
括号使
*
首先与
p
关联。由于
p
是指向
int
数组的指针,因此要到达
int
需要额外的解引用:

printf("%i\n", (*p)[i][j]);
定义
display
以获取指向数组的指针意味着数组的大小绑定到类型参数,因此
display
确切地知道数组的尺寸

另一种方法是定义
display
,将数组的维度作为第二个参数

void display(int p[][N_COLS], int n_rows)
{
在这种情况下,
p
参数是指向
int
的数组
N_COLS
的指针。在大多数表达式中使用T数组时,T数组将衰减为指向T的指针类型的值,该值等于其第一个元素的地址。因此,您可以这样调用第二个版本的
display

int Array [N_ROWS][N_COLS] = { {1,2,3},{4,5,6},{7,8,9} };
display(Array, N_ROWS);
第二种方法的优点是
display
可以处理行数少于或多于
N_行的数组。缺点是由调用方传递正确的行数

您可能认为以下声明将为您提供完整的类型安全性:

void display(int p[N_ROWS][N_COLS])
{

但是,C中用于函数参数的数组语法会导致忽略
p
的大小信息,并将其等效于
int p[][N_COLS]
,然后将其视为
int(*p)[N_COLS]

您的
显示的原型以及调用语法都不正确:您定义
display
以获取指向
int
的二维指针数组,而如果
int
,则只需要一个二维数组,当您在
main
中传递指向数组的指针时,指针将作为一个点衰减这是它的第一个元素

以下是一个更简单的版本:

void display(int p[N_ROWS][N_COLS]) {
    int i, j;
    for (i = 0; i < N_ROWS; i++) {
        for (j = 0; j < N_COLS; j++) {
            printf("%i", p[i][j]);
        }
    }
}

您的意思可能是函数参数为
int(*p)[N_行][N_列]
您的函数被声明为接受一个指针数组,而您正在向它传递一个指向数组的指针。@M.M:我怀疑OP应该从
p
中删除
*
。请查看
数组的声明和函数参数
p
。然后思考您传递给
p
的内容。(但请注意语义不同)。数组不是指针(反之亦然)。请从函数中删除
*
,并从调用中删除
&
。@user3386109:这将破坏类型检查,并允许调用代码传递,例如
int[1][3]
array作为参数。如果数组大小始终相同,即在编译时固定不变,则最好通过执行上述操作来强制调整大小,即传递指向整个数组的指针。@user3386109:C99 specific
static
在这种情况下,数组大小中的关键字不强制任何内容。它可以作为编译器的提示,b它不触发编译时大小检查。如果你认为这个语法是“复杂的”,你可以通过使用一个中间的<代码> TyPufF数组来大大简化它。
然后声明
A*
参数。@jxr:正如AnT所指出的,您的方法确实改进了类型检查,但您还必须更正OP的代码并使用
printf(“%i”,(*p)[i][j])
@user3386109使用
static
关键字不强制执行约束。它帮助编译器优化,编译器可以发出警告;但是标准要求编译器在任何情况下都编译代码,实际上我所知的编译器都不会发出警告。@chqrlie:一个好的compiler会就
printf
使用错误发出警告。在原型中忽略N_行有什么具体原因吗?这是我唯一感到困惑的地方。@vvid:编译器根本不使用指定为函数参数的数组的大小信息,既不用于类型检查,也不用于
sizeof()
,因为数组是作为指向其第一个元素的指针传递的,并且大小不被视为类型的一部分。这是出于历史原因而被接受的:C的发明者没有想到这会变得误导和容易出错。相反,他们一定认为这是程序员告诉下一位代码读者w的好方法对于数组来说,它的大小是预期的,它本身作为指针指向它的第一个元素。@ VVID来解释为什么<代码> nyReals被忽略,注意JXH建议的替代解决方案意味着<代码> NyReals不再被忽略,所以如果你想它是重要的,你可以考虑这个方法。将数组放在
sizeof()
中,大小信息不会被忽略。但是,C定义了数组语义,主要允许它们“通过引用”进行处理“因此,将数组传递给函数不会导致大量数据被推送到堆栈上。他们的方法是定义数组语义,使其衰减为指针类型,函数使用的就是这种衰减的类型。因此,函数参数看起来像数组,但实际上是指针类型。”