[英]C program strange output and wrong output
晚上好。 我試圖讓以下程序給我平均值,並取整平均值。 到目前為止,我有以下幾點。
使用<math.h>
的round
函數時,它將返回零。 是的,我嘗試使用-std=99
, -lm
和-fno-builtin
編譯。 這些似乎都不重要。 它仍然返回零。
它應該使用ComputeAverage
給出的ave
。 這是我得到奇怪輸出的地方。 運行平均值時,平均值有時顯示為148.28
(應正確)。
但是,我注意到,如果我將其運行到接近上一運行時, -31360458752.00
得到以下示例: 2303125649788529278976.00
, -31360458752.00
, -319407486092479668309433442631680.00
和2618000384.00
。
另外請注意,我仍在添加代碼,但已嘗試確保刪除了對當前情況無用的所有內容。 代碼如下。
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix(Matrix a)
{
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
printf("%g ", a.element[i][j]);
}//Inner for
printf("\n");
}//Outer For
}// printMatrix
float ComputeAverage(Matrix a)
{
float sum;
float average;
int i;
int j;
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
sum += a.element[i][j];
}//inner for
average = sum / 64;
}//for
//a.element[i][j];
printf("Average = %.2f",average);
printf("\n");
// printf ("Testing Sum = %f", sum);
// printf("\n");
}// ComputeAverage
Matrix Q50 = {{16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68,109,103, 77,
24, 35, 55, 64, 81,104,113, 92,
49, 64, 78, 87,103,121,120,101,
72, 92, 95, 98,112,100,103, 99}
};
int main(int argc, const char * argv[])
{
Matrix M = {{154, 123, 123, 123, 123, 123, 123, 136,
192, 180, 136, 154, 154, 154, 136, 110,
254, 198, 154, 154, 180, 154, 123, 123,
239, 180, 136, 180, 180, 166, 123, 123,
180, 154, 136, 167, 166, 149, 136, 136,
128, 136, 123, 136, 154, 180, 198, 154,
123, 105, 110, 149, 136, 136, 180, 166,
110, 136, 123, 123, 123, 136, 154, 136}};
// need to implement PrintMatrix
PrintMatrix(M);
// need to implement ComputeAverage
float ave = ComputeAverage(M);
// need to implement round
int dc = round(ave);
//printf("Ave = %d\n",dc);
return EXIT_SUCCESS;
}
通過使用float ave = ComputeAverage(M);
的float ComputeAverage(Matrix a)
返回(不返回值)來調用未定義行為 float ave = ComputeAverage(M);
通過使用上述未定義行為中調用未定義行為 sum
在未初始化sum += a.element[i][j];
通過將float
傳遞給round(ave)
其中round
需要double
round(ave)
,可以在上述Undefined Behavior中調用Undefined Behavior 。
解決方案 -使ComputeAverage(Matrix a)
類型為double
並return average;
(並清除有關Matrix
初始化程序中缺少大括號的警告),例如
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define _ISOC99_SOURCE
#define N 8
typedef struct _Matrix {
double element[N][N];
} Matrix;
void PrintMatrix (Matrix a)
{
int i;
int j;
for (i=0; i<N; i++) {
for (j=0; j<N; j++)
printf (" %3g", a.element[i][j]);
putchar ('\n');
}
}
double ComputeAverage(Matrix a)
{
double sum = 0;
double average;
int i;
int j;
for (i = 0; i < N; i++) {
for (j=0; j<N; j++)
sum += a.element[i][j];
average = sum / 64.0;
}
return average;
}
Matrix Q50 = {{{ 16, 11, 10, 16, 24, 40, 51, 61 },
{ 12, 12, 14, 19, 26, 58, 60, 55 },
{ 14, 13, 16, 24, 40, 57, 69, 56 },
{ 14, 17, 22, 29, 51, 87, 80, 62 },
{ 18, 22, 37, 56, 68,109,103, 77 },
{ 24, 35, 55, 64, 81,104,113, 92 },
{ 49, 64, 78, 87,103,121,120,101 },
{ 72, 92, 95, 98,112,100,103, 99 }}};
int main (void)
{
Matrix M = {{{ 154, 123, 123, 123, 123, 123, 123, 136 },
{ 192, 180, 136, 154, 154, 154, 136, 110 },
{ 254, 198, 154, 154, 180, 154, 123, 123 },
{ 239, 180, 136, 180, 180, 166, 123, 123 },
{ 180, 154, 136, 167, 166, 149, 136, 136 },
{ 128, 136, 123, 136, 154, 180, 198, 154 },
{ 123, 105, 110, 149, 136, 136, 180, 166 },
{ 110, 136, 123, 123, 123, 136, 154, 136 }}};
PrintMatrix (M);
double ave = ComputeAverage(M);
printf ("ave: %g\n", ave);
int dc = round(ave);
printf ("dc : %d\n", dc);
return EXIT_SUCCESS;
}
使用/輸出示例
$ ./bin/computeavg
154 123 123 123 123 123 123 136
192 180 136 154 154 154 136 110
254 198 154 154 180 154 123 123
239 180 136 180 180 166 123 123
180 154 136 167 166 149 136 136
128 136 123 136 154 180 198 154
123 105 110 149 136 136 180 166
110 136 123 123 123 136 154 136
ave: 148.281
dc : 148
啟用編譯器警告
始終在啟用警告的情況下進行編譯,並且不要接受代碼,直到代碼在沒有警告的情況下干凈地進行編譯 。 要啟用警告,請在您的gcc
或clang
編譯字符串中添加-Wall -Wextra
。 (添加-pedantic
以獲得其他一些警告)。 對於clang
,您可以使用-Weverything
(但這包括許多無關的警告)。 對於gcc / clang,建議:
-Wall -Wextra -pedantic -Wshadow
對於VS (windoze上為cl.exe
),添加/W3
(或使用/Wall
但您會收到很多無關的非代碼相關警告)。
閱讀並理解每個警告。 他們將確定任何問題以及發生問題的確切路線。 通過聽編譯器告訴您的內容,您可以學到很多東西。
如果您還有其他問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.