【问题标题】:2-d Array and pointer. [duplicate]二维数组和指针。 [复制]
【发布时间】:2018-04-18 11:39:01
【问题描述】:
{
int a[10][10]={{1,2,3},{4,5,6},{7,8,9}};
int n;
n=FindSumLeavingOutRowCol(a, 3,3,1,2);
printf("%d",n);

}
int FindSumLeavingOutRowCol(int** arr, int m, int n, int k,int l)
{
int sum,i,j;
for(i=0;i<m;i++)
{
    for(j=0;j<n;j++)
    {
        if((i==k)&&(j==l))
        {
            ;
        }
        else{
            sum+=*(*(a+i)+j);
        }
    }
    }

我在传递 2 d 数组时遇到一个错误,它告诉 'a' 未声明。请帮我解决错误!

【问题讨论】:

  • 第一步:格式化此代码,使其可读。此外,我们需要minimal reproducible example,因此复制和粘贴、编译和运行可以重现您的问题。
  • a 未声明不是错误。稍后编译代码时会出现错误...这里似乎a 声明在与函数不同的(非全局)范围内,因此不可见。
  • 顺便说一句,a 的类型为 int [10][10],因此在调整为指针后,这是 int (*)[10]不是 int **,正如您的函数所期望的那样。跨度>
  • sum+=*(*(a+i)+j); 中的变量 a 没有被声明,也没有被初始化。编译器试图找到它,但它无法找到它。也许你打错了或想使用另一个变量。
  • 二维数组不是指针数组!您可以查看我的另一个 answer 以了解更多详细信息(是 C++,但对于原始数组来说完全一样)

标签: c arrays multidimensional-array


【解决方案1】:

表达式中的数组,例如当用作参数时,会被转换为指向它们的第一个元素的指针。

如果你有这样的数组

int a[10][10];

可以像这样重写

int ( a[10] )[10];

也就是说,它是一个由 10 个元素组成的数组,类型为 int[10[,然后在表达式中它被转换为类型 int ( * )[10]

所以例如你可以写

int ( a[10] )[10] = { {1,2,3}, {4,5,6}, {7,8,9} };
int (  *p   )[10] = a;

因此函数应该被声明为

int FindSumLeavingOutRowCol( int arr[][10], int m, int n, int k,int l);

与此相同

int FindSumLeavingOutRowCol( int ( *arr )[10], int m, int n, int k,int l);

如果编译器支持变长数组并且变量mn 代表维度(不是范围),那么函数也可以声明为

int FindSumLeavingOutRowCol( int m, int n, int arr[m][n], int k,int l);

int FindSumLeavingOutRowCol( int m, int n, int arr[][n], int k,int l);

或喜欢

int FindSumLeavingOutRowCol( int m, int n, int ( *arr )[n], int k,int l);

否则,您将需要添加另外两个参数来指定尺寸以外的范围。

注意变量sum没有初始化

int sum,i,j;

所以函数会有未定义的行为。

此外,参数被声明为具有名称arr 而不是a

我希望函数有类似的返回语句

return sum;

【讨论】:

  • int FindSumLeavingOutRowCol( int m, int n, int arr[m][n], int k,int l); :由于mn 表示数组中的范围,而不是维度,因此您需要使用不同的参数而不是n 作为维度([n])。跨度>
  • @BLUEPIXY 谢谢。我已经更新了我的帖子。
【解决方案2】:

让我们从简单的开始:

它的“a”也未声明。

int FindSumLeavingOutRowCol(int** arr, int m, int n, int k,int l)
{
    // [...]
            sum+=*(*(a+i)+j);
    // [...]
}

在这一行中,您引用了a,它既不存在于文件范围内,也不存在于此函数中。你可能指的是arr


但真正的问题是你的第一个问题:

我在传递二维数组时遇到错误

这是因为您的函数需要一个指向指针的指针,该指针不是指向二维数组(的第一个元素)的指针。

来自n1570 (latest draft for C11)

§6.7.6.3 函数声明符(包括原型),p7:

将参数声明为“类型的数组”应调整为“限定指针 type'',其中类型限定符(如果有)是在 [] 的 数组类型推导。 [...]

因此,由于数组不能传递给函数,而是传递指针,如果您将函数参数声明为数组类型,它会自动调整为指针类型。

这对于一维数组很简单。说你有

int x[5];

还有一个函数

void foo(int a[]);

那么这个函数声明就等价于

void foo(int *a);

你可以像这样传递你的数组

foo(x);

因为数组的标识符也计算为指向第一个数组元素的指针 --> 类型 int *

对于二维数组,同样的规则适用。您可以使用如下参数编写函数:

int foo(int arr[][10]);

将此调整为指针类型会导致

int foo(int (*arr)[10]);

这是一个 指向 int 的 10 元素数组的指针。它不是指向指针的指针int a[10][10] 的 10 个元素都是一个 10 个整数的数组。

【讨论】:

    猜你喜欢
    • 2014-06-20
    • 2019-09-09
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 2021-12-17
    相关资源
    最近更新 更多