【问题标题】:Passing a two dimensional array by reference in C在C中通过引用传递二维数组
【发布时间】:2015-11-19 05:50:14
【问题描述】:

我在作业问题上需要帮助。

作业的描述是:

用C语言设计一个程序,使用引用调用的方法,它 生成由 M 个学生组成的班级的成绩统计信息 在一个学期的课程中进行 N 次测验。测验全部 进行同等权重,每个测验的成绩为 10 分 点。该程序将按照指示的顺序执行以下操作 程序执行时:

  1. 要求用户在键盘上输入学生人数M和测验次数N,M代表人数 行数和 N 表示二维中的列数 浮点数数组 x[M][N]。
  2. 要求用户在键盘上键入数组 x[M][N] 的所有元素的值。
  3. 在控制台上显示输入的数组元素值的M行N列。
  4. 生成并在控制台上显示一维数组 p[M] 的元素,其中该数组的每个元素 p[M] 代表每个 M 学期的平均成绩 学生。
  5. 生成并在控制台上显示一维数组 q[N] 的元素,其中 q[N] 的每个元素代表 N 个测验中每个测验的班级平均成绩。
  6. 生成并在控制台上显示整个学期整个班级的平均成绩 z。

这是我到目前为止所做的代码:

#include <stdio.h>
#define students 300
#define quizzes 20

void averageGradeOfStudents(int M, int N, float p[], float *xPtr);
float averageGradeOfClass();
float averageGradeOfWholeClass();

int main() {
    int M, N;
    float x[students][quizzes];

    printf("Enter the number students (Maximum: 300): ");
    scanf_s("%d", &M);

    printf("\nEnter the number of Quizzes (Maximum: 20): ");
    scanf_s("%d", &N);

    for (int i = 0; i < M; i++) {
        for (int k = 0; k < N; k++) {
    printf("Enter the grade for student %d, Quiz %d: ", i, k);
            scanf_s("%f", &x[i][k]);
        }
    }
    printf("\n--------------------------------------------------------------------------------\n\n");

    for (int k = 1; k <= N; k++) {
        printf("\t\tQuiz%d", k);
    }

    for (int i = 0; i < M; i++) {
        printf("\nStudent%d Grades: ", i);
        for (int k = 0; k < N; k++) {
            printf("%.2f\t\t", x[i][k]);
        }

    }
    printf("\n\n\n--------------------------------------------------------------------------------\n\n");

    float p[students];
    averageGradeOfStudents(M, N, p, &x[0][0]);

    float q[quizzes];

    float z;

    getchar();
    return 0;
}

void averageGradeOfStudents(int M, int N, float p[], float *xPtr) {
    float grade[students];

    for (int i = 0; i < M; i++) {
        for (int k = 0; k < N; k++) {
            grade[i] += *(xPtr + i);
        }
    }

    for (int k = 0; k < M; k++) {
        p[k] = grade[k] / N;
        printf("The average grade of student%d is: %.2f\n\n", k, p[k]);
    }    
}
float averageGradeOfClass() {



}

float averageGradeOfWholeClass() {



}

我遇到的问题是我无法找到一种方法来单独对数组的每一行求和。

【问题讨论】:

    标签: c multidimensional-array


    【解决方案1】:

    你的任务取得了很好的进展。获得完整的代码和努力令人耳目一新。在我们达到平均水平之前,有几件事会有所帮助。首先,也是很好的做法,初始化你的变量。对于数组尤其如此,因为它可以防止意外尝试读取未初始化的值,并且在字符数组的情况下,可以为第一次复制到数组提供自动 null-termination(只要你只复制 size-1 个字符)。

        int M = 0, N = 0;
        float x[students][quizzes] = {{ 0 }};
        float p[students] = {0};
        float q[quizzes] = {0};
        float z = 0;
    

    传递数组始终是一个问题区域。传递声明为二维数组的数组时,必须将数组的宽度作为函数参数的一部分传递:

    void averageGradeOfStudents (int M, int N, float p[], float xPtr[][quizzes]);
    

    然后你可以简单地通过传递数组本身来调用函数。

        averageGradeOfStudents (M, N, p, x);
    

    (注意: 任何数组的第一级间接寻址在作为函数参数传递时都会转换为指针,但这是稍后问题的主题。但是,供您参考,您的函数声明也可以正确写为):

    void averageGradeOfStudents (int M, int N, float p[], float (*xPtr)[quizzes]);
    

    现在平均而言,您已经接近了,您只需要通过更改索引xPtr 的方式来对每个学生的元素求和(并初始化grade 的值):

    void averageGradeOfStudents (int M, int N, float p[], float xPtr[][quizzes]) 
    {
        float grade[M];
    
        /* initialize variable length array to 0 */
        for (int i = 0; i < M; i++) grade[i] = 0;
    
        /* sum of grades for each student */
        for (int i = 0; i < M; i++) {
            for (int k = 0; k < N; k++) {
                grade[i] += xPtr[i][k];
            }
        }
    
        printf ("The average grades for the students are:\n\n");
        for (int k = 0; k < M; k++) {
            p[k] = grade[k] / N;
            printf("  student[%3d] is: %6.2f\n", k, p[k]);
        }    
    }
    

    在完整代码中使用它的一个简单示例可能是:

    #include <stdio.h>
    #define students 300
    #define quizzes 20
    
    void averageGradeOfStudents (int M, int N, float p[], float (*xPtr)[quizzes]);
    
    int main (void) {
    
        /* good habit -- always initialize your variables */
        int M = 0, N = 0;
        float x[students][quizzes] = {{ 0 }};
        float p[students] = {0};
    
        printf("Enter the number students (Maximum: 300): ");
        scanf ("%d", &M);
    
        printf("\nEnter the number of Quizzes (Maximum: 20): ");
        scanf ("%d", &N);
    
        for (int i = 0; i < M; i++) {
            for (int k = 0; k < N; k++) {
                printf("Enter the grade for student %d, Quiz %d: ", i, k);
                scanf("%f", &x[i][k]);
            }
        }
        printf("\n--------------------------------------------------------------------------------\n\n");
    
        printf ("                        ");
        for (int k = 1; k <= N; k++) {
            printf(" Quiz%-2d", k);
        }
        putchar ('\n');
    
        for (int i = 0; i < M; i++) {
            printf("\n  Student[%3d] Grades: ", i);
            for (int k = 0; k < N; k++) {
                printf(" %6.2f", x[i][k]);
            }
        }
        printf("\n\n--------------------------------------------------------------------------------\n\n");
    
        averageGradeOfStudents (M, N, p, x);
    
        /* getchar(); */
        return 0;
    }
    
    void averageGradeOfStudents (int M, int N, float p[], float (*xPtr)[quizzes]) 
    {
        float grade[M];
    
        /* initialize variable length array to 0 */
        for (int i = 0; i < M; i++) grade[i] = 0;
    
        /* sum of grades for each student */
        for (int i = 0; i < M; i++) {
            for (int k = 0; k < N; k++) {
                grade[i] += xPtr[i][k];
            }
        }
    
        printf ("The average grades for the students are:\n\n");
        for (int k = 0; k < M; k++) {
            p[k] = grade[k] / N;
            printf("  student[%3d] is: %6.2f\n", k, p[k]);
        }
        putchar ('\n');
    }
    

    使用/输出

    $ ./bin/studentavg
    Enter the number students (Maximum: 300): 3
    
    Enter the number of Quizzes (Maximum: 20): 3
    Enter the grade for student 0, Quiz 0: 8
    Enter the grade for student 0, Quiz 1: 9
    Enter the grade for student 0, Quiz 2: 8
    Enter the grade for student 1, Quiz 0: 9
    Enter the grade for student 1, Quiz 1: 9
    Enter the grade for student 1, Quiz 2: 10
    Enter the grade for student 2, Quiz 0: 7
    Enter the grade for student 2, Quiz 1: 8
    Enter the grade for student 2, Quiz 2: 9
    
    --------------------------------------------------------------------------------
    
                             Quiz1  Quiz2  Quiz3
    
      Student[  0] Grades:    8.00   9.00   8.00
      Student[  1] Grades:    9.00   9.00  10.00
      Student[  2] Grades:    7.00   8.00   9.00
    
    --------------------------------------------------------------------------------
    
    The average grades for the students are:
    
      student[  0] is:   8.33
      student[  1] is:   9.33
      student[  2] is:   8.00
    

    注意:我已将系统的 scanf_s 更改为 scanf,您需要将其更改回来。如果您还有其他问题,请告诉我。

    【讨论】:

      【解决方案2】:

      在你知道 M 和 N 的值之前,我不会声明数组。所以main 的第一部分如下所示。 (这也允许您转储 studentsquizzes 常量。)并始终检查库函数的返回值。

      int main( void )
      {
          int M, N;
      
          printf("Enter the number students (Maximum: 300): ");
          if ( scanf_s("%d", &M) != 1 || M > 300 ) {
              printf( "Whatever\n" );
              exit( 1 );
          }
      
          printf("\nEnter the number of Quizzes (Maximum: 20): ");
          if ( scanf_s("%d", &N) != 1 || N > 20 ) {
              printf( "Sigh...\n" );
              exit( 1 );
          }
      
          float x[M][N];
      
          // ...
      }
      

      将数组传递给函数时,可以使用数组表示法。并且您可以省略数组的第一个维度。所以下面两个函数声明都是有效的

      void averageGradeOfStudents(int M, int N, float p[M], float x[M][N]);    
      void averageGradeOfStudents(int M, int N, float p[], float x[][N]);
      

      函数内部,有一些问题

      • grade[i] 在使用前未初始化(这应该会导致编译器警告)
      • 每个grade[i] 应该是N 个等级的平均值(索引为k 而不是i
      • 您实际上并不需要 grade 数组,因为您已经拥有 p 数组

      这是我编写函数的方式(我更改了索引名称以保持行和列清晰)

      void averageGradeOfStudents(int M, int N, float p[], float x[][N])
      {
          for (int row = 0; row < M; row++) {
              p[row] = 0;                         // initialize the sum to zero
              for (int col = 0; col < N; col++) {
                  p[row] += x[row][col];          // update the sum with each test result
              }
              p[row] /= N;                        // convert the sum to the average
          }
      
          for (int row = 0; row < M; row++) {
              printf("The average grade of student%d is: %.2f\n\n", row, p[row]);
          }    
      }
      

      并且该函数应该被调用

      averageGradeOfStudents(M, N, p, x);
      

      【讨论】:

        【解决方案3】:

        对数组求和是一个相当常见的习惯用法:

        double sumArray(double arr[], int arrLen)
        {
            int i;
            double sum = 0.0;
            for (i = 0; i < arrLen; i++)
                sum += arr[i];
        
            return sum;
        }
        

        这是一个一维数组的总和,但请记住,数组x 的每一行都是一维数组。

        【讨论】:

          【解决方案4】:
          int avg=0;
          int sum=0;
          for (int i = 0; i < M; i++) {
                  for (int k = 0; k < N; k++) {
              printf("Enter the grade for student %d, Quiz %d: ", i, k);
                      scanf("%f", &x[i][k]);
                      sum=sum+x[i][k]
                  }
              }avg=sum/M;
          

          要获得平均值,您必须求和...试试这可能会对您有所帮助

          【讨论】:

          • 是的,我原来是这样做的;但我必须使用引用方法调用。
          猜你喜欢
          • 2020-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-24
          • 1970-01-01
          • 2015-07-08
          • 2018-06-30
          • 2010-10-06
          相关资源
          最近更新 更多