C программа странный вывод и неправильный вывод - PullRequest
0 голосов
/ 10 ноября 2018

Добрый вечер. Я пытался, чтобы следующая программа дала мне среднее значение и среднюю величину. Пока у меня есть следующее.

При использовании функции <math.h> round возвращается ноль. Да, я попытался скомпилировать с -std=99, -lm и -fno-builtin. Кажется, ничего из этого не имеет значения. Это все еще возвращает ноль.

Следует использовать ave, заданное ComputeAverage. Вот где я получаю странный вывод. Среднее значение иногда отображается как 148.28 (что должно быть правильным) при запуске.

Тем не менее, я заметил, что если запустить его близко к предыдущему, я получу следующие примеры: 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;
}

1 Ответ

0 голосов
/ 10 ноября 2018

Вы вызываете Неопределенное поведение , используя возврат float ComputeAverage(Matrix a) (который не возвращает значения) в float ave = ComputeAverage(M);

Вы вызываете Неопределенное поведение в указанном выше Неопределенное поведение с помощью sum неинициализировано в sum += a.element[i][j];

Вы вызываете Неопределенное поведение в обоих вышеуказанных Неопределенное поведение , передавая float в round(ave), где round ожидает double.

Решение - Сделайте 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

Включить предупреждения компилятора

Всегда компилировать с включенными предупреждениями , а не принимать код, пока он не скомпилируется без предупреждения . Чтобы включить предупреждения, добавьте -Wall -Wextra в строку компиляции gcc или clang. (добавьте -pedantic для нескольких дополнительных предупреждений). Для clang вместо этого вы можете использовать -Weverything (но это включает многочисленные посторонние предупреждения). Для обоих gcc / clang рекомендуем:

 -Wall -Wextra -pedantic -Wshadow

Для VS (cl.exe при windoze) добавьте /W3 (или используйте /Wall, но вы получите довольно много посторонних предупреждений, не связанных с кодом).

Прочитайте и поймите каждое предупреждение. Они будут определять любые проблемы и точную линию, на которой они возникают. Вы можете многому научиться, слушая, что говорит ваш компилятор.

Дайте мне знать, если у вас есть дополнительные вопросы.

...