1 Востаннє редагувалося Пам'ять не може бути READ (30.01.2013 19:55:24)

Тема: Неправильний результат під час виконання програми

Привіт. Почався в мене в бурсі такий предмет як програмування,
ну і дали нам на дз написати програмку на c, яка обчислює середнє арифметичне 3 чисел з плаваючою комою.
Власне я с до того не вчив, але розібратися з основними операторами не склало великої мороки.
Та так сталося, що в мене при певній ситуації, виникає помилка.
Ось повний код робочої програми:

#include<stdio.h>

 double average(double number1, double number2, double number3)
 {
    return (number1 + number2 + number3) / 3;
 }

 int main(void)
 {
    float n1,n2,n3;
  printf("Введіть 3 числа \n");    
  scanf("%f %f %f",&n1,&n2,&n3); 
  printf("Середнє арифметичне: %5.2f",average(n1,n2,n3));
  return 0;
 }

А проблема заключається у тому, що якщо

float n1,n2,n3;

Замінити на

double n1,n2,n3;

То компілятор каже таке:

program.c:12:3: warning: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double *’ [-Wformat]
program.c:12:3: warning: format ‘%f’ expects argument of type ‘float *’, but argument 3 has type ‘double *’ [-Wformat]
program.c:12:3: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double *’ [-Wformat]

Тото матюкається на цю

scanf("%f %f %f",&n1,&n2,&n3);

строку.
Але при цьому всьому програма компілюється, але якщо наприклад задати 3 числа( 3,3,3)
то результатом буде:

902945129852059871903106368162024652800.00

Чим викликано такий результат ? У чому причина ?

2

Re: Неправильний результат під час виконання програми

#include <stdio.h>

int main(int argc, char *argv[])
{
    float a, b, c;
    printf("Input 3 numbers (1 2 3)\n");
       scanf("%f %f %f", &a, &b, &c);
    printf("Arithmetic average of %2.2f %2.2f and %2.2f is %.3f\n", a, b, c, (a + b + c)/3);
    return 0;
}

3 Востаннє редагувалося Ярослав (30.01.2013 20:12:08)

Re: Неправильний результат під час виконання програми

Фіксити вашу проблему так:

 double average(double (double) number1, double (double) number2, double (double) number3)

або так

  printf("Середнє арифметичне: %5.2f",average( (double) n1, (double) n2, (double) n3));

Одне із двох.
Такі проблеми виникають, коли щось не так із типом.

4

Re: Неправильний результат під час виконання програми

Компілятор не матюкається тут, а сором'язливо натякає, що там варто би використати змінні іншого типу. Програма компілюється, оскільки типи float та double взаємосумісні.

Сіль у малопомітних тонкощах.

1. keithfay вірно визначив причину і підказав варіант щодо явного приведення типів під час виклику функції у

printf("Середнє арифметичне: %5.2f",average( (double) n1, (double) n2, (double) n3));

Це дозволить, можливо, змусити компілятор припнути язика щодо зведення типів.
Щоправда, це не вирішить проблеми №2.

2. Те, що у вас сталося зі значенням результату, пояснюється розмірами змінних. Кодом

scanf("%f %f %f", &a, &b, &c);

ви намагалися зчитати до змінних a,b,c дані, по 4 байти до кожної. При цьому змінні мають тип double, а отже, вимагають 8 байт, а 4 старших байти з 4 - це не зовсім те саме, що 4 з 8...

Код виправляється так:

#include<stdio.h>
 
 double average(double number1, double number2, double number3)
 {
    return (number1 + number2 + number3) / 3;
 }
 
 int main(void)
 {
    float n1,n2,n3;
  printf("Введіть 3 числа \n");    
  scanf("%lf %lf %lf",&n1,&n2,&n3); 
  printf("Середнє арифметичне: %5.2lf",average(n1,n2,n3));
  return 0;
 }

'lf' тут позначає 'double'. Якщо використати 'Lf' - матимемо long double.

5

Re: Неправильний результат під час виконання програми

keithfay написав:
 double average(double (double) number1, double (double) number2, double (double) number3)

А так не варто робити: компілятор буде лаятися. :)

Re: Неправильний результат під час виконання програми

Bartash написав:

Компілятор не матюкається тут, а сором'язливо натякає, що там варто би використати змінні іншого типу. Програма компілюється, оскільки типи float та double взаємосумісні.

Сіль у малопомітних тонкощах.

1. keithfay вірно визначив причину і підказав варіант щодо явного приведення типів під час виклику функції у

printf("Середнє арифметичне: %5.2f",average( (double) n1, (double) n2, (double) n3));

Це дозволить, можливо, змусити компілятор припнути язика щодо зведення типів.
Щоправда, це не вирішить проблеми №2.

2. Те, що у вас сталося зі значенням результату, пояснюється розмірами змінних. Кодом

scanf("%f %f %f", &a, &b, &c);

ви намагалися зчитати до змінних a,b,c дані, по 4 байти до кожної. При цьому змінні мають тип double, а отже, вимагають 8 байт, а 4 старших байти з 4 - це не зовсім те саме, що 4 з 8...

Код виправляється так:

Прихований текст
#include<stdio.h>
 
 double average(double number1, double number2, double number3)
 {
    return (number1 + number2 + number3) / 3;
 }
 
 int main(void)
 {
    float n1,n2,n3;
  printf("Введіть 3 числа \n");    
  scanf("%lf %lf %lf",&n1,&n2,&n3); 
  printf("Середнє арифметичне: %5.2lf",average(n1,n2,n3));
  return 0;
 }

'lf' тут позначає 'double'. Якщо використати 'Lf' - матимемо long double.

Дивно, та компілятор всеодно лається на ту саму стрічку.

7

Re: Неправильний результат під час виконання програми

Hanter написав:

Дивно, та компілятор всеодно лається на ту саму стрічку.

Темна ніч, консоль та g++ під рукою - прогавив цей момент. Вибачаюся.

Просто замініть змінним тип з float на double.

З.І: Попередження про рух float->double малосуттєве і не є загрозою. Але не double->float...