Логическая ошибка при усреднении нескольких разных чисел и выводе результата

#c #math

#c #математика

Вопрос:

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

 // integer_sequence_avg.c
// Inputs a sequence of integers then averages them and outputs the result after the sentinel value "9999" is entered.
#include <stdio.h>

int main(void) {
    // initializaiton
    int addend = 0;
    int sum = 0;
    int average;
    unsigned int counter;
    
    for (addend; addend != 9999;   counter) {   
        printf("%s", "Enter an integer to be averaged. Enter "9999" when you want to receive the average: "); // prompt to enter integers to be averaged
        scanf("%d", amp;addend); // scans input into variable to be added to sum
        
        if (addend != 9999) {
            sum  = addend; // Adds addend to sum
        }
    }
    
    if (counter != 0) {
        average = sum / counter; // Calculates average
        
        printf("nThe average of the integers added was %dnn", average); // Outputs average of numbers entered
    } else {
        printf("nNo integers were entered.nn"); // Outputs that no integers were entered
    }
    
    system("pause");
    
    return 0;
}
  

скриншот логической ошибки
https://i.stack.imgur.com/Fwwaa.png

Комментарии:

1. Просто в качестве примечания: небезопасно использовать scanf без проверки возвращаемого значения. См. Эту страницу для получения дополнительной информации: руководство для начинающих по scanf()

Ответ №1:

  • counter увеличивается без инициализации. Это вызвало неопределенное поведение.
  • counter увеличивается, даже если addend != 9999 равно false .
  • Возвращаемые значения scanf() должны быть проверены, чтобы убедиться, что они успешно прочитаны.

Вместо этого

     unsigned int counter;
    
    for (addend; addend != 9999;   counter) {   
        printf("%s", "Enter an integer to be averaged. Enter "9999" when you want to receive the average: "); // prompt to enter integers to be averaged
        scanf("%d", amp;addend); // scans input into variable to be added to sum
        
        if (addend != 9999) {
            sum  = addend; // Adds addend to sum
        }
    }
  

Попробуйте это:

     unsigned int counter = 0;
    
    while ( addend != 9999 ) {   
        printf("%s", "Enter an integer to be averaged. Enter "9999" when you want to receive the average: "); // prompt to enter integers to be averaged
        if (scanf("%d", amp;addend) != 1) break; // scans input into variable to be added to sum
        
        if (addend != 9999) {
            sum  = addend; // Adds addend to sum
              counter;
        }
    }
  

Ответ №2:

Проблема здесь:

 for (addend; addend != 9999;   counter) {
  

where counter не инициализируется перед использованием.

Исправление: unsigned int counter = 0;

Единственное, на что следует обратить внимание, это то, что counter значение увеличивается один раз сверх того, что должно, что дает неправильные результаты.

например, для этих входных данных:

 4 6 8 9 
  

Среднее значение должно быть 27/4 == 6 , но counter == 5 только после 4 записей
среднее значение вычисляется как 27/5 == 5

Для устранения этого
изменения average = sum / counter;
Для average = sum / (counter - 1);

Кроме того, целочисленное деление приводит к округлению, поэтому, если числитель не содержит все простые множители знаменателя, результат будет вызывать целочисленное округление. Если это вызывает беспокойство, следует учитывать переменные с плавающей запятой.

Комментарии:

1. до сих пор ни одно из решений не работало. есть ли что-нибудь еще, что я могу попробовать?

2. @jtlwsejiejyj445 — Я обновил свой ответ. counter отключается 1 при вводе последнего ввода (до 9999 ).