被告知我的C程序是“硬编码”,我不明白为什么

时间:2014-07-10 19:28:02

标签: c programming-languages

我将我的作业转到了我的在线C编程课程,由于我的程序被硬编码,而且我无法看到它将如何被考虑,因此我很难停靠。硬编码"因为我要求用户输入。以下是我的代码:

#include <stdio.h>
#include <stdlib.h>

#define IMAX 3
#define JMAX 4

int main()
{   
    float a[IMAX][JMAX];
    float avgrow[5];
    float avgcol[5];
    int i,j;
    char c;

    printf ("This program will allow you to enter numbers for 3 rows and 4 columns from         left to right then filling down, and take the averages of the rows and columns and list them next to the row and under the columns. You may use decimals but only 2 will display in the results. Press enter!\n");
    scanf ("%c",&c);

    printf("Enter 12 numbers here for your rows and columns:\n");
    for(i = 0; i < IMAX; i++)
    {
        for(j = 0; j < JMAX; j++)
        {
            scanf("%f",&a[i][j]);
        }
    }
    for(j = 0; j < JMAX; j++)
    {
        avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
        avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
        avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
    }
    for(i=0; i < IMAX; i++)
    {
        avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
        avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
        avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
        avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
    }

    printf("  Column1         Column2         Column3         Column4         Row Average\n\n");
    printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
    printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]);
    printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
    printf("\n");
    printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);

    return 0;
}

所有它应该做的是制作一个包含3行和4列的2-d数组,然后取行的平均值并显示在表格中的行旁边。比较列的平均值并将其显示在表格中的列下方。

这是他对我的任务的评论&#34;嗯,你得到了正确的答案,但在处理二维数组时,你应该使用嵌套的for循环。不是一个循环,然后是很多&#34;硬编码&#34;价值观进入计划。&#34;

任何解密这个的帮助都会受到赞赏,因为我终于理解了编程,直到这个。

7 个答案:

答案 0 :(得分:8)

首先,谈论一个硬编码的程序是没有意义的。相反,人们会谈论硬编码的特定值。这意味着您将它们的值直接写入代码中,而不是将它们放在一个可以轻松更改的常量或变量中。

在这种情况下,您硬编码的值是行数和列数。你确实有这些常量,但你不能始终如一地使用它们。也就是说,如果您更改常量以将数组转换为5x5数组,则代码现在会中断,因为部分代码仍然会像3x4数组一样。

具体而言,代码中有两个循环,您可以通过拼写出该范围内的每个索引而不是使用循环来访问索引[0] [0]到[2] [3]。这意味着如果您更改IMAX和JMAX,它仍将使用那些相同的索引,这些索引不再正确。

因此,您的数组索引是硬编码的,更改数组维度会破坏您的程序。

答案 1 :(得分:5)

for(j = 0; j < JMAX; j++)
{
    avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
    avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
    avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
    avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
    avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
    avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
    avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}

注意复制/粘贴几乎相同的代码?这通常是硬编码的标志 - 代码文本或结构中存在常量。你如何改变3和4?它们“很难” - 内置于代码中。

证明这是一个问题 - 你有:

#define IMAX 3
#define JMAX 4

但是如果你真的改变了那些,那么代码就会破裂。看看这行代码:

    avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;

这是一个平均值,当且仅当JMAX为4.代码是在JMAX必须为4的情况下构建的 - JMAX被“硬编码”为4。

答案 2 :(得分:5)

查看以下代码:

for(j = 0; j < JMAX; j++)
{
    avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
    avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
    avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}

此代码假定a 总是有3行4列,无论实际声明a的方式如何。例如,如果您将JMAX更改为2,则上面的代码会中断,因为a的维度为3x2,并且您试图访问数组边界之外的元素。

你的导师正在寻找的东西是这样的:

for(j = 0; j < JMAX; j++)
{
  float sum = 0.0;

  for (i = 0; i < IMAX; i++ )
  {
    sum += a[i][j];
  }
  avgrow[j] = sum/JMAX;
}

此代码不会假设a的维度超出IMAXJMAX指定的范围。

另请注意,avgrowavgcol的声明已经硬编码为5,而它们也应基于IMAXJMAX

float avgrow[IMAX];
float avgcol[JMAX];

答案 3 :(得分:2)

float avgrow[5];
float avgcol[5];

for(j = 0; j < JMAX; j++)
 {
    avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
   avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
   avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}

for(i=0; i < IMAX; i++)

{
   avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
   avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
   avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX; 
   avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;

}

printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]); 
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
printf("\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);

您所采取的所有步骤都是难以编码的,因为您特别注意指数如果超过imax和jmax值的变化那么您必须手动更改/添加avgcol [index]以取平均值和输出值...

你的程序应该独立于它,它应该只取决于i max和jamx的值

作为参考,您可以查看我已删除硬编码的代码示例

http://ideone.com/mXymKS

虽然这段代码可以在很大程度上简化......

答案 4 :(得分:1)

您已为avgrowavgcol的数组索引使用显式整数值。为避免硬编码,请尝试使用带整数变量的循环作为索引,例如

  

for(int k = 0; k <4; ++ k)

然后将值赋给avgrow [k]。

答案 5 :(得分:1)

您的教授希望您能够轻松修改程序中的行数和列数。您编写的程序的缺点是修改这两个参数之一需要您更改整个程序。您可以获得更多灵活性,例如:

#include <stdio.h>
#include <stdlib.h>

#define IMAX 3
#define JMAX 4

int main()
{   
    float a[IMAX][JMAX];
    float avgrow[IMAX] = {0};
    float avgcol[JMAX] = {0};

    printf ("This program will allow you to enter numbers for %d rows"
            "and %d columns from left to right then filling down, and"
            " take the averages of the rows and columns and list them"
            " next to the row and under the columns. You may use "
            "decimals but only 2 will display in the results. Press"
            " enter!\n", IMAX, JMAX);
    char c;
    scanf ("%c",&c);

    printf("Enter %d numbers here for your rows and columns:\n", IMAX * JMAX);
    for(int i = 0; i < IMAX; i++) {
        for(int j = 0; j < JMAX; j++) {
            scanf("%f",&a[i][j]);     
        }
    }

    for(int i = 0; i < IMAX; i++) {
        for(int j = 0; j < JMAX; j++) {
            avgrow[i] += a[i][j];
        }
        avgrow[i] /= JMAX;
    }

    for(int j = 0; j < JMAX; j++) {
        for(int i = 0; i < IMAX; i++) {
            avgcol[j] += a[i][j];
        }
        avgcol[j] /= IMAX;
    }

    for(int i = 0; i < IMAX; i++) {
        printf("Column%d\t", i);
    }
    printf("Row-Average\n\n");

    for(int j = 0; j < JMAX; j++) {
        for (int i = 0; i < IMAX; i++) {
            printf("%8.2f\t", a[i][j]);
        }
        printf("%8.2f\n", avgrow[j]);
    }
    for(int i = 0; i < IMAX; i++) {
        printf("%8.2f\t", avgcol[i]);
    }

    return 0;
}

答案 6 :(得分:1)

除了已经存在的丰富答案之外,我还想指出一些关于acquiring datacomputing averages的内容,而不需要多次重复:

所以定义你的平均数组:

float avgrow[IMAX] ={0};
float avgcol[JMAX] ={0};

然后在您scanf用户条目的同一循环中,您可以同时计算这样的平均值:

printf("Enter %d numbers here for your rows and columns:\n", IMAX*JMAX);
for(i = 0; i < IMAX; i++)
{
    for(j = 0; j < JMAX; j++)
    {
        scanf("%f",&a[i][j]);
        avgrow[i] += a[i][j]/JMAX;
        avgcol[j] += a[i][j]/IMAX;
    }
}

下一步就是打印出所有内容,让它自动化:)

for(i=1; i<= JMAX; i++) printf("Column%d\t\t", i);
printf("Row Average\n");
for(i=0; i<IMAX; i++)
{
    for(j=0; j<JMAX; j++) 
    {
        printf("%8.2f\t", a[i][j]);
    }
    printf("%8.2f\n", avgrow[i]);
}
for(i=0; i<JMAX; i++)
printf("%8.2f\t", avgcol[i]);

在END 你有一个代码来计算任何大小的行和col平均值。即尝试更改IMAXJMAX