我试图创建一个减法函数使用指针为二维数组,但当我运行它,我得到
表达式必须具有指向对象的指针类型,但它具有类型"int" C/C ++(142)
有人能解释一下为什么我会得到这个错误,还有什么更好的方法吗?
这是我的密码
读取数组的函数
int *readMatrix(int *arr)
{
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
printf("row %d, col %d: ", i + 1, j + 1);
scanf("%d", &arr[i * 4 + j]);
}
}
printf("\n");
return arr;
}
用于减去2个2D阵列的函数
int *subM(int *arrA, int*arrB, int *arrC){
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 4; ++j)
{
//printf("row %d, col %d: ", i + 1, j + 1);
&arrC[i][j] = &arrA[i][j] - &arrB[i][j]; //code where I am getting error
}
}
return arrC;
}
主要功能
int main()
{
int arrA[3][4];
int arrB[3][4];
int arrC[3][4];
readMatrix(&arrA[3][4]);
readMatrix(&arrB[3][4]);
subM(&arrA[3][4],&arrB[3][4],&arrC[3][4]);
return 0;
}
3条答案
按热度按时间umuewwlo1#
我是StackOverflow的新手。如果我不能很好地表达自己,我很抱歉,但是我想我找到了解决你问题的方法。
让我们一步一步地看一下。
1.当将数组传递给函数时,不需要编写下标。
这意味着,与此相反:
就写这个:
您还可以(实际上应该)删除指针运算符(&),因为当只使用数组名时,它会自动充当指针。
现在我们来看一下readMatrix的定义。
对多维数组使用指针是可以的,但是编译器会发出很多警告。
最标准的方法是在函数定义中使用下标:
对于您的情况,有两种方法可以访问多维数组。
或者告诉编译器这个函数接受多维数组:
而不是这个:
请执行以下操作:
代码将如下所示:
而不是这个:
试试这个:
使用其中一种方法,但第一种方法似乎更标准,因为编译器不会在第一种方法上抛出警告。
1.返回值
你可能知道接下来会发生什么。我只是在写代码。
取代:
我更喜欢这个警告较少:
原因很简单,它实际上指向同一个地址,但却让编译器守口如瓶。
我想就是这样了。最后的代码应该是这样的:
编译良好,无警告。
这些代码片段只是我的推荐。如果你想知道用C做某事的最标准方法,你可能要去查一下。一本好书也是推荐的。例如,我用Stephen Prata的C Primer Plus学习了C。一本很棒的书,有很多例子和插图来帮助你理解情况。
再次为我的英语道歉。我想还有很长的路要走。
如果我遗漏了什么或在什么地方犯了错误,请让我知道。
编辑:是斯蒂芬·普拉塔,不是斯蒂芬;)
vbopmzt12#
根据下标运算符
[]
的定义,表达式相当于:
因此,
相当于:
如果你把这个应用到
它相当于:
该表达式
无效,原因如下:
该子表达式
的类型为
int
,因为解引用int *
会产生int
。也将计算为
int
。在计算完该子表达式后,尝试使用非法的
*
运算符取消对int
的引用。只能取消对指针类型的引用。子表达式
以及
有完全相同的问题,在这两个表达式中也都是在解引用
int
。实际问题是您使用以下参数声明了函数
subM
:在C中,数组通常通过传递一个指向(外部)数组第一个元素的指针(可能是decayed)传递给函数。
因此,如果您向函数传递的是一维数组,则参数类型
int *
是正确的,但对于二维数组则不正确。这是因为指向二维int
数组的外部数组的第一个元素的指针在您的情况下具有int (*)[4]
类型,即指向4个int
元素的一维数组的指针。但是,您传递的是指向单个int
对象(不是数组)的指针,因此您传递的指针类型错误。因此,应将参数类型更改为以下类型:
这样写可能更清楚一些:
这两行是等效的,因为数组decay在用作函数参数时指向指针。
同样,你应该改变你调用函数的方式。你应该改变
致:
由于array to pointer decay,该行等效于:
8fq7wneg3#
几个问题...
readMatrix
使用int *arr
参数[正确]。但是,我们希望它与sumM
兼容sumM
使用int *
参数,但尝试使用二维数组语法取消引用它们。1.在
sumM
中,使用(例如)&arr[i][j]
是元素的 * 地址 *,而不是 * 它的 * 值 * [这是我们想要的]。1.在
main
中,我们传递(例如)&arr[3][4]
。它指向数组的 end,所以这是UB(未定义行为)。我们希望传递数组的起始地址(例如arr
或&arr[0][0]
)。1.不需要将指针传递回结果数组,因为调用方将地址作为参数传递。
下面是重构后的代码,它带有注解:
在上面的代码中,我使用了
cpp
条件来表示旧代码和新代码:注意:通过
unifdef -k
运行文件可以清除此问题