從型別的文本檔案中讀取資料后,我試圖計算平均值int。程式編譯得很好。clang -std=gnu11 -Weverything -g3 -pedantic -g3 -O3 -lm average_weight_of_elephant_seals.c -o average_weight_of_elephant_seals
假設我想計算 2000 個印章的平均重量,預期輸出為 6838.848152 但我得到 1710.566467。我還不知道如何理解 GDB。
有人可以指出我哪里出錯了嗎?
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (!feof(elephant_seal_data))
{
fscanf(elephant_seal_data, "%i", &weight);
weights_array[count ] = weight;
sum = weight;
count ;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
uj5u.com熱心網友回復:
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
該代碼無緣無故地將指向某個位置的指標傳遞到陣列中,并且不檢查 number_of_seals * 2 是否小于 MAXSIZE,因此可能會溢位陣列。但是這個計算無論如何都不需要陣列。
weights_array[count ] = weight;
sum = weight;
count ;
代碼正在寫入陣列而不是讀取它。此計算不需要陣列。
代碼增量計數兩次,因此平均值將超出兩倍,并且陣列中的備用位置將具有未定義的值。
uj5u.com熱心網友回復:
您的代碼中有 2 個愚蠢的錯誤,一個更嚴重的錯誤,一個是risk。
首先是愚蠢的:
您傳遞count給函式并為檔案中的每個值增加兩次該值。如果初始給定的值是正確的,那么您的計數會大 3 倍。你不應該傳遞count給函式,而是在那里計算它。
你使用了錯誤的語法來傳遞一個陣列:你應該傳遞一個指向它的第一個元素的指標。
現在是討厭的一個:while為什么“while (!feof (file))”總是錯誤的?確實是一個FAQ,在初學者代碼中仍然是一個常見的東西......
feof僅在讀取操作回傳錯誤后回傳 true 。讓我們檢查最后一個值會發生什么。它被讀取并正確處理一次。feof仍然回傳false(到目前為止沒有錯誤),因此您的代碼重新進入回圈。scanf到達檔案末尾并回傳 0(您的代碼忽略的內容)但不更改值 => 最后一個值將被處理兩次。從不使用while (!feof(...
最后是風險。
您正在將值求和為一個整數。即使平均值很容易適應那里,如果你有更大的值并且它們的數量非常多,你可能會得到一個整數溢位。將其匯總為更大型別(雙精度?)的推薦方法,如果可能的話,使用猜測來限制累積誤差:平均值(數量猜測) 猜測確實是平均值(數量),但計算的總和可能要低得多,在使用浮點值時限制累積誤差或在使用整數值時防止溢位。從密封的數量和預期的平均值來看,這里應該沒有問題,所以猜測是沒有用的,但請記住,對于不同的用例......
最后但并非最不重要的,main預計隨著中宣告int main(),如果你不進行額外的引數,但關心從未 int main(void)
代碼可以變成:
/* The following program demonstrates the usage of fscan to read in a set of integer data into a file and then computes the sum followed by the average.
* The computation shall be encapsulated in a function and then be called in the main routine
*/
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int* count, int weights_array[]);
int main()
{
int number_of_seals;
int weights_array[MAXSIZE];
double weight = average_weight(&number_of_seals, weights_array);
printf("Their number is %d and their average weight is %lf\n", number_of_seals, weight);
return 0;
}
double average_weight(int* count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
FILE* elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
*count = 0;
/* FEOF function to determine if EOF has been reached or not */
for(int i=0; i<MAXSIZE; i ) // never process more than the array size
{
if (1 != fscanf(elephant_seal_data, "%i", &weight)) {
break; // immediately stop at end of file
}
weights_array[(* count) ] = weight;
sum = weight;
}
double average_weight = (double)sum / (double)*count;
fclose(elephant_seal_data);
return average_weight;
}
我保持您的一般程式結構不變,但是恕我直言,您應該首先將資料讀入一個陣列,然后將該填充的陣列及其計數傳遞給一個平均函式。只需將您當前的功能分成 2 個步驟。
uj5u.com熱心網友回復:
您已經發送了要在陣列中使用的計數數量,這很棒,因為該函式不知道 weights_array 的長度。但是您沒有正確使用它。
我建議你:
- 用于
count根據需要的資料數量限制回圈次數。 - 不要更改/重新分配 的值
count。因為這個數字對于計算平均值至關重要。創建一些其他變數來完成任務。
因此,這就是我如何稍微修改您的代碼以帶來這些更改。我假設大象_seal_data.txt 的格式為空格分隔的整數值。
#include <stdio.h>
#define MAXSIZE 5000 /* Macro definition to pre-define the size of the array */
double average_weight(int count, int weights_array[]);
int main(void)
{
int number_of_seals;
int weights_array[MAXSIZE];
printf("Enter the number of seals: \n");
scanf("%i", &number_of_seals);
printf("Their average weight is %lf\n", average_weight(number_of_seals, &weights_array[number_of_seals]));
return 0;
}
double average_weight(int count, int weights_array[])
{
/* Variable declaration and initialization
* Note the use of the FILE data type */
int weight;
int sum = 0;
int i = 0;
FILE *elephant_seal_data = fopen("elephant_seal_data.txt", "r");
if (elephant_seal_data == NULL)
{
return -1;
}
/* FEOF function to determine if EOF has been reached or not */
while (!feof(elephant_seal_data) && (i<count))
{
fscanf(elephant_seal_data, "%i", &weight);
weights_array[i ] = weight;
sum = weight;
}
double average_weight = (double)sum / (double)count;
fclose(elephant_seal_data);
return average_weight;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/405977.html
標籤:
