Программа C странный вывод и неправильный вывод

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

При использовании функции <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;
}

Ваш компилятор не выдает предупреждений с помощью этого кода? Если нет, включите их (-Wall -Wextra для gcc и clang. Возможно, вам также придется скомпилировать с -O, чтобы увидеть самый важный из них).

Shawn 10.11.2018 06:21

Почему у вас double element и float ComputeAverage? Разница в ширине составляет 32 бита. Далее - вы ничего не return из ComputeAverage, так что можете сделать это и void.

David C. Rankin 10.11.2018 06:21

Также вы должны получить предупреждение о неинициализированной локальной переменной float sum;, измените ее на float sum = 0;, и функция ComputeAverage должна вернуть average.

Barmak Shemirani 10.11.2018 06:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
111
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы вызываете Неопределенное поведение, используя возврат 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

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

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

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

Доброе утро, спасибо за ответ. У меня изначально сумма была инициализирована равной 0,0, и я вообще пропустил оператор return :(. Мой вопрос: есть ли у вас ссылка на официальную документацию для библиотек C? Единственная документация, которую я нашел о встроенной функции раунда в C сказал, что требуется double / float / longs, поэтому я бы не стал рассматривать изменение значений float на double. Есть ли что-нибудь конкретное, что вы предлагаете мне прочитать или послушать во время учебы, чтобы помочь с обучением? Или больше практики, чем что-либо?

Tyreese Davis 10.11.2018 19:17

Другие вопросы по теме