簡體   English   中英

被告知我的C程序是“硬編碼”,我不明白為什么

[英]Was told my C program was “hard coded” and I don't understand why

我把我的作業轉到了我的在線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維數組,然后取行的平均值並顯示在表格中的行旁邊。 比較列的平均值並將其顯示在表格中的列下方。

這是他對我的任務的評論“嗯,你得到了正確的答案,但是當處理二維數組時,你應該使用嵌套for循環。不是一個for循環,然后很多”硬編碼“值進入程序“。

任何解密這個的幫助都會受到贊賞,因為我終於理解編程直到這個。

首先,談論一個硬編碼的程序是沒有意義的。 相反,人們會談論硬編碼的特定值。 這意味着您將其值直接寫入代碼中,而不是將它們放在可以輕松更改的常量或變量中。

在這種情況下,硬編碼的值是行數和列數。 你確實有這些常量,但你不能始終如一地使用它們。 也就是說,如果您更改常量以將數組轉換為5x5數組,則代碼現在會中斷,因為代碼的某些部分仍然會像3x4數組一樣。

具體來說,代碼中有兩個循環,您可以通過拼寫出該范圍內的每個索引而不是使用循環來訪問索引[0] [0]到[2] [3]。 這意味着如果您更改IMAX和JMAX,它仍將使用那些相同的索引,這些索引不再正確。

因此,您的數組索引是硬編碼的,更改數組維度會破壞您的程序。

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。

查看以下代碼:

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];
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

雖然這段代碼可以在很大程度上簡化......

您已經為avgrowavgcol的數組索引使用了顯式整數值。 要避免硬編碼,請嘗試使用帶有整數變量的循環作為索引,例如,

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

然后將值賦給avgrow [k]。

您的教授希望您能夠輕松修改程序中的行數和列數。 您編寫的程序的缺點是修改這兩個參數之一需要您更改整個程序。 您可以實現更多靈活性,例如:

#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;
}

除了已經存在的豐富答案之外,我想指出一些關於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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM