【问题标题】:Why can't I pass a 2D array into this defined function?为什么我不能将二维数组传递给这个定义的函数?
【发布时间】:2016-04-12 15:49:02
【问题描述】:
int checkdiag(int arr[][100], int size)
{
    int h=0,i,j,count=0;
    for(i=0;i<size;i++)
        for(j=0;j<size;j++)
            if(arr[i][j]==arr[++i][++i])
                count++;
    if(count=size)
        h=1;        
    return(h);
}

这个函数应该检查我的二维数组,看看是否所有的对角线都是相同的值。最大数组大小为 100 x 100。

int 
main(void)  
{
    int r,c,**m,i,j;  
    FILE*in;
    in=fopen("matrix.txt","r");
    fscanf(in,"%d",&r);
    c=r;
    m=(int**)malloc(r*sizeof(int*));

    for(i=0;i<r;i++)
        m[i]=(int*)malloc(c*sizeof(int));

    for(i=0;i<r;i++)
    {   
        for (j=0; j<c; j++)
        {
            fscanf(in,"%d",&m[i][j]);
        }
    }
    fclose(in);
    checkdiag(m,r)
    return(0);
}

【问题讨论】:

  • 你想做什么?
  • 我有一个来自数据文件的二维数组,我需要编写一个函数来确定对角线的所有值是否都是相同的值。
  • 您能否展示您实际尝试将二维数组传递给该函数的代码?
  • 不,我需要更多。显示您定义 m 和 r 的代码,并将其包含在您的问题中。
  • 顺便说一句,“所有对角线都是相同的值”你是指对角线上的所有元素还是你真的想检查所有 (199) 对角线是否只有 199 个不同的值?就像在 { {1,2,3},{4,1,2},{5,4,1}} 中?

标签: c arrays dynamic


【解决方案1】:

在C语言中要将二维作为函数参数传递,需要指定数组的长度,以及每个数组元素的长度。

您在问题中提供的代码应该使用 C99 时工作。否则,您必须指定每个数组元素的长度和长度。

你不能简单地用变量指定数组长度和元素长度而不声明这些变量-

void array_function(int array[][n]);  //Wrong!
void array_function(int array[m][]);  //Wrong!
void array_function(int array[m][n]); //Wrong!

不过,您也可以接受这些变量作为参数,或者硬编码您的数组和数组元素的长度 -

void array_function(int n, array[][n])         //Correct!
void array_function(int m, int n, array[m][n]) //Correct!

void array_function(int m, array[m][100])      //Correct!
void array_function(int n, array[100][n])      //Correct!

void array_function(int array[100][100]);      //Correct!
void array_function(int array[100][100]);      //Correct!

接受不同长度的数组 -

要传入具有不同大小(长度和元素长度)的函数,您需要在将数组传递给函数时指定长度和元素长度。所以你的函数原型应该是这样的:

void array_function(int m, int n, array[m][n]) //Correct!

使用 C99 标准,您可以省略第一个大小变量,并允许长度未知的数组,但该数组中的每个数组具有相同数量的元素 -

void array_function(int m, array[][m]) //Correct, with C99!  

但是对于您的代码,我不确定您为什么在函数中硬编码值 100。如果你打算接收数组并用它们的对角线做一些事情,我假设你只会得到方阵。你应该这样写你的函数:

void array_function(int size, array[size][size])

void array_function(int size, array[][size])

我推荐第一个选项,因为它清楚地表明您接受方阵。

【讨论】:

【解决方案2】:

多个问题:

首先mainm的类型与checkDiagarr的类型不匹配; int **int [][100]int (*)[100] 的简写)不兼容。

如果您希望类型匹配,请声明m,如下所示:

int (*m)[100]; // m is a *pointer* to a 100-element array of int

然后,当您分配m 时,请执行以下操作:

m = malloc( r * sizeof *m ); // allocates space for an r x 100 array of int

这种方法的优点是你在一次操作中分配了整个数组,并且保证了行是连续的。

请注意,如果 r 不是 100,您将不会分配“方形”矩阵。不过,这对于您正在做的事情来说应该不是什么大问题,因为您只是通过r 元素阅读和检查r。不过,如果你想成为一个坚持不懈的人,你可以这样做:

 int r;
 // get value of r
 int (*m)[r] = malloc( r * sizeof *m );

这会动态分配intr x r 数组。我们使用可变长度数组语法(即使用变量r 来定义数组大小)。请注意,可变长度数组是在 C99 中引入的,在 C2011 中是可选的;您需要确保您的实现支持它们1

在第二种情况下,您需要将 checkDiag 的原型从

int checkDiag( int arr[][100], int size )

int checkDiag( int size, int arr[][size] )

size 必须先声明,然后才能在 VLA 声明中使用。

在任何一种情况下,您都只需在完成后调用free( m ); 来释放数组。

第二大问题checkDiag中的这一行:

 if(arr[i][j]==arr[++i][++i])

这一行调用了未定义的行为;您在序列点之间多次更新i 的值,并且您尝试在同一个表达式中同时使用旧值和递增值(即使那样,它在逻辑上也没有意义)。尝试类似以下的方法:

for ( i = 0; i < size - 1; i++ )
{
  if ( arr[i][i] == arr[i+1][i+1] )
    count++;
}

最后一期是一行

if(count=size)

您想在这里使用== 而不是=;您只是将size 分配给count,并且由于结果非零,因此将h 设置为1。将其更改为

if ( count == size )
  h = 1;

或者,您可以完全放弃 h 变量而只写

return count == size;


1。要以编程方式执行此操作,请查找功能宏 __STDC_NO_VLA__,如下所示:
#if defined( __STDC_NO_VLA__ )
#error "VLAs are not available for this implementation!"
#endif

【讨论】:

    【解决方案3】:

    不确定您想要什么,但我假设您想检查 主对角线 中的所有元素是否相同。在这种情况下,二维数组在两个维度上的大小必须相同。我不知道您使用的是什么语言,但这段代码应该可以满足您的需求:

    int checkdiag(int** arr, int size)
    {
        int d=arr[0][0];
        for(int i=1;i<size;i++)
           if(arr[i][i]!=d)
               return 0;     
        return 1;
    }
    

    如果所有对角线元素都相同,则返回值为 1,否则为 0。

    要检查所有对角线是否相同,您必须对每个对角线执行此过程。

    编辑:然后你可以这样调用函数:

    int** arr;
    int size = 100;
    arr=(int**)malloc(size*sizeof(int*));
    for(int i=0;i<size;i++)
        arr[i]=(int*)malloc(size*sizeof(int));
    
    //fill array with values
    int ret = checkdiag(arr,size);
    

    Edit2: Sice OP 分享了更多信息,我更新了checkdiag 以使用指针。

    【讨论】:

    • 我收到此错误:从不兼容的指针类型传递“checkdiag”的参数 1。
    • 也许更好:int d = arr[0][0]; for( int i = 1; i &lt; size; i++ ) { if ( arr[i][i] != d ) return 0; } return 1;...
    • 问题不一定出在逻辑或算法上,它是 C 编程语言特有的。
    • @Bob__ 这是真的。我会改的。
    • 考虑到 OP 将 arr 声明为指向 int 的指针(第二个 sn-p 已发布)not as a 2D array,最好的签名是 int checkdiag(int **arr, int size)。请注意,我不是在责怪你。
    猜你喜欢
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多