如何将数组的元素数量传递给函数

时间:2019-04-06 17:36:15

标签: c arrays function average

我想将数组的n个元素部分传递给函数,以计算平均值。 本质上,我想使代码中的元素数量保持动态,以便可以输入自定义数字。

float average(float num[]); 

int main() 
{ 
  int n,i,k; 
  float num[n]; 
  printf("Enter the numbers of elements: "); 
  scanf("%d",&k);
  for(i = 0; i < k; ++i)
  {
    printf("%d. value: ", i+1);
    scanf("%f", &num[i]);
  }
  printf("Average = %.2lf",average(num)); 
  return 0;
}

float average(float num[])
{
  int i,n;
  float sum = 0.0, avg;
  n = sizeof(num)/sizeof(int);

  for(i = 0; i < n; ++i)
  {
    sum += num[i];
  }
  avg = sum / n;
  return avg;
}

n = sizeof(num)/sizeof(int);在某种程度上没有传递正确数量的元素。 我尝试在网络上进行挖掘,尝试了其他选项,但似乎没有任何正常工作。 我猜这是因为我没有正确地将数组传递给函数..但不知道如何,请指教,非常感谢

2 个答案:

答案 0 :(得分:2)

在C中将数组作为函数参数传递时,它会“调整”为指针。在C11中,它是§6.7.6.3¶7:

  

将参数声明为“ 类型的数组”声明调整为“指向 type 的合格指针”,其中指定了类型限定符(如果有)在数组类型派生的 [] 中。如果关键字 static 也出现在数组类型派生的 [] 中,则对于每次调用该函数,相应的实际参数应提供对数组第一个元素的访问,该元素的大小至少应与size表达式指定的数量相同。

也就是说,您可以通知编译器和/或其他工具(例如静态分析工具),另一个参数带有长度,但是该参数必须在 之前。进入是一个好习惯。有关更多信息,请参见 SEI CERT C编码标准中的API05-C

问题是编译器很讨厌它。首先,只有在C≥C99中才允许使用一致的数组参数,因此,如果您的代码被严格认为是C89或它们将无法正常工作。

即使一致的数组参数是(值得商)的)not variable length arrays,大多数编译器基本上还是这样对待,并且编译器对VLA的支持还很差。 C11甚至使对VLA的支持成为可选。 MSVC根本不实现它们。如果您在启用-Wvla的情况下使用GCC和Clang(至少),则会发出警告。 PGI有一个错误,会导致编译失败。 IAR还将它们视为VLA,并且如果您不启用可变长度数组(默认情况下,支持为关闭,但有一个命令行开关可启用它们),则会发出警告。 Tiny C编译器也会发出错误; IIRC,因为它也将它们视为VLA。

也就是说,我仍然喜欢使用它们。它使代码更易于理解,智能静态分析工具可以利用它们更好地检查代码。但是,如果要使代码可移植,则需要将其隐藏在诸如the one I have in Hedley之类的宏后面。

无论您是否要使用一致的数组参数,都需要修改代码。您既可以将数组作为两个参数传递,也可以创建一个封装长度和数组的类型……两个参数绝对是惯用的解决方案。因此对于您的原型,您最终会得到类似

的信息
// No conformant array parameters, just another parameter
float average(size_t n, float num[]);
// CAP
float average(size_t n, float num[n]);
// CAP with a macro
float average(size_t n, float num[ARRAY_PARAM(n)]);

sizeof(num)仍将等于sizeof(float*)(因为它就是它),但是至少您知道数组中有多少个元素。

答案 1 :(得分:1)

主要

  float num[n]; 

必须移至下方,因为 n 未初始化,因此:

 int n,i,k; 
 float num[n]; 
 printf("Enter the numbers of elements: "); 
 scanf("%d",&k);

必须像

 int i,k; 

 printf("Enter the numbers of elements: "); 
 if (scanf("%d",&k) != 1) {
   puts("invalid size");
   return -1;
 }
 float num[k]; 

平均值中:

n = sizeof(num)/sizeof(int);

是错误的,因为 num 中的元素数量未知,因此sizeof(num)会计算指针的大小,您需要给出参数中的元素数量

 float average(float num[], int n); 

主要

printf("Average = %.2lf",average(num, k)); 

float average(float num[], int n)
{
  int i;
  float sum = 0.0;

  for(i = 0; i < n; ++i)
  {
    sum += num[i];
  }

  return sum / n;
}