C程序奇怪的输出和错误的输出

时间:2018-11-10 05:12:41

标签: c matrix rounding math.h

晚上好。我试图让以下程序给我平均值,并取整平均值。到目前为止,我有以下几点。

使用<math.h>的{​​{1}}函数时,它将返回零。是的,我尝试使用round-std=99-lm进行编译。这些似乎都不重要。它仍然返回零。

它应该使用-fno-builtin给定的ave。这是我得到奇怪输出的地方。平均值在运行时有时显示为ComputeAverage(应该正确)。

但是,我注意到,如果我将其运行到接近前一次运行,则会得到以下示例:148.282303125649788529278976.00-31360458752.00-319407486092479668309433442631680.00

另外请注意,我仍在添加代码,但已尝试确保删除了对当前情况无用的所有内容。 代码如下。

2618000384.00

1 个答案:

答案 0 :(得分:2)

您通过使用float ComputeAverage(Matrix a)中的float ave = ComputeAverage(M);(不返回值)的返回值来调用未定义行为

您可以通过使用sum中未初始化的sum += a.element[i][j];来调用上述未定义行为中的未定义行为

您通过在float中将round(ave)传递到rounddouble中来调用上述两个 Undefined Behavior 中的 Undefined Behavior 。 {1}}。

解决方案-将ComputeAverage(Matrix a)键入doublereturn 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,但您会收到很多无关的与代码无关的警告) 。

阅读并理解每个警告。他们将确定任何问题以及发生问题的确切路线。通过听编译器告诉您的内容,您可以学到很多东西。

如果您还有其他问题,请告诉我。