繁体   English   中英

arrays 中的混淆

[英]Confusion in arrays


最近我正在学习 arrays 传递给函数(通过将它们的基地址传递给在 function 中定义为参数的指针,然后使用指针算法随后提取整个数组)
为了练习,我被要求计算 70 名学生的 class 的平均分数,他们的分数列在名为“marks”的数组中,并被要求定义一个带有参数的变量作为指针并从那里计算平均值。
给我的数据是学生 1 得 40 分,学生 2 得 41 分,学生 3 得 42 分……以此类推。

这是我的尝试:

 #include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> float average(int *b) { int sum = 0; for (int i = 1; i <= 70; i++) { sum = sum + *b; b = b + 1; } printf("the value of sum is %d\n", sum); // this value is changing every time I run the program return (((float)sum) / 70); } int main() { int marks[70]; marks[0] = 40; for (int i = 0; i < 68; i++) { marks[i + 1] = marks[i] + 1; } printf("the value of marks of 10th child is %d\n", marks[9]); // Just for checking if I am correct,(yes; the ans does come out to be 49;) printf("the value of average marks of the class is %f\n", average(&marks[0])); return 0; }

令我惊讶的是,每次运行它时,值都会不断变化。 谁能提示我哪里错了?

您的问题与您的数组未初始化的事实(如我的评论中所述)有关。

memory 已分配,但仍是随机的混乱数据。 幸运的是,您覆盖了数组中所有条目的数据,最后一个除外。 最后一个入口在这一点上基本上是一个随机值。

所以这就是 output 不断变化的原因,你的实际错误有点简单。

在计算总和的 for 循环中,从i = 0迭代到i = 67 因此,使用 +1 偏移量,您可以将所有条目从 1 更改为 68,因此不会触及最后一个入口( marks[69] )。

固定代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
float average(int *b) {
  int sum = 0;
  for (int i = 1; i <= 70; i++) {
    sum = sum + *b;
    b = b + 1;
  }
  printf("the value of sum is %d\n",
         sum); // this value is changing every time I run the program
  return (((float)sum) / 70);
}

int main() {
  int marks[70];
  marks[0] = 40;
  for (int i = 0; i < 68; i++) {
    marks[i + 1] = marks[i] + 1;
  }
  printf("the value of marks of 10th child is %d\n",
         marks[9]); // Just for checking if I am correct!(yes! the ans does come
                    // out to be 49!)
  printf("the value of average marks of the class is %f\n", average(&marks[0]));

  return 0;
}

PS:在average function 中,您使用指针算法循环输入数组,这被很多人认为是不好的做法。 此外,您基本上不使用您创建的 for 循环增量变量( int i )。 一种更简单、更安全的方法是:

float average(int *b) {
  int sum = 0;
  for (int i = 0; i < 69; i++) {
    sum += b[i];
  }
  printf("the value of sum is %d\n",
         sum); // this value is changing every time I run the program
  return (((float)sum) / 70);
}

我被要求计算70名学生的 class 的平均分数,他们的分数列在名为“marks”的数组中

在发布的代码中,我们可以找到以下声明

int marks[70];

大小是正确的,但请注意它是未初始化的,因此其元素的值是不确定的。 但是,代码会尝试在之后立即分配正确的值。

marks[0] = 40; // "student 1 scored 40, student 2 scored 41, student 3 scored 42...
               //  and so on." 

for (int i = 0; i < 68; i++)
{ //            ^^^^^^ 
    marks[i + 1] = marks[i] + 1;
} //      ^^^^^ 

分配的最后一个标记是marks[67 + 1] ,它使marks[69] (数组的实际最后一个元素)未确定。

有很多方法可以达到正确的结果,有些人可能会觉得以下合适。

int marks[70] = { 40 };

for (int i = 0; i + 1 < 70; ++i)
{ //         ^  ^^^^^^^^^^ 
    marks[i + 1] = marks[i] + 1;
}    

我正在学习 arrays 传递给函数(通过将它们的基地址传递给在 function 中定义为参数的指针,然后使用指针算法随后提取整个数组)

使用索引通常会产生更具可读性的代码,因此我不会在以下代码段中使用“指针算法”。

我建议总是传递数组的大小,而不仅仅是指针。

注意有多少“神奇”数字,比如 70 和错误的 68,在整个发布的代码中散布(和重复),限制了它的通用性并增加了出错的机会。

我还将前一个片段的逻辑提取到单独的 function 中,易于修改和测试。

#include <stdio.h>

double average(size_t n, int *marks)
{
  long sum = 0;
  for (size_t i = 0; i < n; ++i)
  {
    sum += marks[i];
  }
  return (double)sum / n;
}

void fill_linear(size_t n, int *arr, int first_value)
{
  for (size_t i = 0; i < n; ++i)
  { 
    arr[i] = first_value++;
  }
}

int main(void)
{
  enum { n_students = 70 };

  int marks[n_students];
  fill_linear(n_students, marks, 40);

  printf("Average: %.1f\n", average(n_students, marks));  // Average: 74.5
  return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM