【问题标题】:C - use a 2d-array as argument [duplicate]C - 使用二维数组作为参数[重复]
【发布时间】:2016-08-22 19:26:50
【问题描述】:

我写了一个很小的 ​​c 程序。 GCC 4.8.5 20150623(Red Hat 4.8.5-4)使用-std=c99成功编译的代码,但给了我一个警告。我无法处理警告,我什至不知道它有什么问题。代码在这里:

#include <stdio.h>
#define COLS 4
int SumOf2DArray(const int array[][COLS], int rows);
int SumOfArray(const int array[], int element_number);
int main(void) {
  int sum_of_array0, sum_of_2d_array, sum_of_array1;
  int *array, (*dimensions)[COLS];
  array = (int [2]){10, 20};
  dimensions = (int [2][COLS]){{1, 2, 3, -9}, {4, 5, 6, -8}};
  sum_of_array0 = SumOfArray(array, 2);
  sum_of_2d_array = SumOf2DArray(dimensions, 2);
  sum_of_array1 = SumOfArray((int []){4, 4, 4, 5, 5, 5}, 6);
  printf("sum_of_array0 = %d \t sum_of_2d_array = %d \t sum_of_array1 = %d\n",
    sum_of_array0, sum_of_2d_array, sum_of_array1);
  return 0;
}
int SumOf2DArray(const int array[][COLS], int rows) {
  int sum_of_2d_array = 0;
  for (int rows_i = 0; rows_i < rows; rows_i++) {
    for (int cols_i = 0; cols_i < COLS; cols_i++) {
      sum_of_2d_array += array[rows_i][cols_i];
    }
  }
  return sum_of_2d_array;
}
int SumOfArray(const int array[], int element_number) {
  int sum_of_array = 0;
  for (int i = 0; i < element_number; i++) {
    sum_of_array += array[i];
  }
  return sum_of_array;
}

警告就在这里:

chapter10_compound_literals.c: In function ‘main’:
chapter10_compound_literals.c:25:3: warning: passing argument 1 of ‘SumOf2DArray’ from incompatible pointer type [enabled by default]
   sum_of_2d_array = SumOf2DArray(dimensions, 2);
   ^
chapter10_compound_literals.c:15:5: note: expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’
 int SumOf2DArray(const int array[][COLS], int rows);

现在,我假设我有一个二维数组:int array[2][3] = {{1, 2, 3}, {3, 4, 5}},我有一个函数:int SumOf2DArray(const int array[][3], int rows)

上面代码中的方式是使用指针(int (*pointer)[3] = array),但得到一个警告,我尝试直接使用array传递参数,但同样的警告。

如何将数组传递给函数?

【问题讨论】:

  • 我猜你的问题是“为什么const int (*)[4]int (*)[4] 不兼容”?
  • 在副本中,指针类型不同,但原因是一样的。
  • 这个问题中的代码会产生任何警告,即使使用-Weverything编译也是如此。
  • @user3386109 是的。你编译错了:ideone.com/YLIL5A
  • 谢谢,我在这里找到了答案:stackoverflow.com/questions/28062095/…

标签: c arrays gcc compilation compound-literals


【解决方案1】:

我认为编译器输出中最清楚地说明了答案:

expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’

int 类型实际上与 const int 完全不同。如果您尝试更改任何 const(例如分配给它),则可以认为您的代码有错误,但显然您可以更改 int。我的建议是不要使用 const,除非你知道自己在做什么——这可能需要一些研究,因为随着类型变得复杂,const 会变得复杂。

【讨论】:

  • 感谢您的回答。我已将 SumOF2DArray() 修改为 int SumOf2DArray(int array[][COLS], int rows);警告消失了。然而,这不是我想要的。 SumOF2DArray() 不会改变array[][COLS] 的值,所以我认为在函数中添加const 是一种很好的风格。让我困惑的是SumOfArray() 也有const,但没有警告。
  • 好吧,您已经确定了问题所在,但您的解释性段落与问题没有任何关系。该代码不会尝试更改任何 const ints
  • 据我了解,“问题”是编译器警告,而不是程序的行为。因此,我认为程序的行为离题了。 (当然,所有程序员都希望确保他们的程序始终正确运行,所以我不需要提醒这一点,对吗?)。也就是说,代码被“固定”为不生成警告的方式不应该改变结果。一般来说,除非有其他错误,否则删除 const 永远不会这样做——它可能会影响性能/占用空间。
  • 关于将 const 保留在适用的代码中的问题,在这一点上答案是显而易见的(至少是简短的答案)。如果你想让一个过程在一个 const 上运行,那么给它传递一个 const。 (我认为将非 const 转换为 const 是没有意义的,但也许编译器会被欺骗这样做。
  • 即便如此,这对我来说还是个糟糕的主意。请注意,您对变量类型进行编码的方式与您实际使用它的方式完全不同。我可以将布尔值编码为浮点数并将其分配给 0/1 并检查它是否大于或小于 0.5。那很可能是愚蠢的,但代码会起作用。您可以根据代码应执行的操作更改或不更改非常量。您可以传递参数而不使用它。你不能做的是假装 const 和 non-const 是同一类型。
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 2019-05-11
  • 2016-01-10
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
相关资源
最近更新 更多