晚上好。我试图让以下程序给我平均值,并取整平均值。到目前为止,我有以下几点。
使用<math.h>
的{{1}}函数时,它将返回零。是的,我尝试使用round
,-std=99
和-lm
进行编译。这些似乎都不重要。它仍然返回零。
它应该使用-fno-builtin
给定的ave
。这是我得到奇怪输出的地方。平均值在运行时有时显示为ComputeAverage
(应该正确)。
但是,我注意到,如果我将其运行到接近前一次运行,则会得到以下示例:148.28
,2303125649788529278976.00
,-31360458752.00
和-319407486092479668309433442631680.00
。
另外请注意,我仍在添加代码,但已尝试确保删除了对当前情况无用的所有内容。 代码如下。
2618000384.00
答案 0 :(得分:2)
您通过使用float ComputeAverage(Matrix a)
中的float ave = ComputeAverage(M);
(不返回值)的返回值来调用未定义行为
您可以通过使用sum
中未初始化的sum += a.element[i][j];
来调用上述未定义行为中的未定义行为
您通过在float
中将round(ave)
传递到round
到double
中来调用上述两个 Undefined Behavior 中的 Undefined Behavior 。 {1}}。
解决方案-将ComputeAverage(Matrix a)
键入double
和return average;
(并清除{中的有关缺失括号的警告{1}}初始化程序),例如
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
或-Wall -Wextra
编译字符串中添加gcc
。 (添加clang
以获得其他一些警告)。对于-pedantic
,您可以使用clang
(但这包括许多无关的警告)。对于这两个gcc / clang,建议:
-Weverything
对于 VS (在windoze上为 -Wall -Wextra -pedantic -Wshadow
),添加cl.exe
(或使用/W3
,但您会收到很多无关的与代码无关的警告) 。
阅读并理解每个警告。他们将确定任何问题以及发生问题的确切路线。通过听编译器告诉您的内容,您可以学到很多东西。
如果您还有其他问题,请告诉我。