Почему моя программа возвращает адрес памяти?

#c

#c

Вопрос:

Я написал программу под названием averageFloat, которая должна принимать отсканированный ввод числа. Это позволяет пользователю вводить несколько входных данных с плавающей запятой, а затем функция принимает среднее значение этих входных данных.

Однако, когда я скомпилировал и запустил программу, она приняла мои входные данные, но вернула -1610612736.

Я уже пытался изменить хранилище для scanf, я добавил указатель и включил глобальные переменные, которые scanf будет вызывать в функции main и averageFloat.

 #include <stdio.h>

float averageFloat(int a);

int y;
float z; 

int main()
{
    int n;
    printf("Please input a number of floats you want to include "); 
    n = scanf("%d", amp;y); 
    averageFloat(n);

    return 0;
}

float averageFloat(int a){

    for(int i = 0; i < a; i  ){
        printf("Please enter the float variables you want your program to average");
        scanf("%f", amp;z); 
        z  = z;
    }
    printf("the average float is %d", z/a);
    return z / a; 
}
  

Я ожидаю, что для этого потребуется ввести n, скажем, n = 5.

Я ожидаю, что смогу ввести 5 чисел с плавающей запятой, скажем 0,5, 0,2, 0,3, 0,1 и 1,5, а затем разделить это на n

Спасибо за чтение.

Ответ №1:

В вашем коде есть пара проблем:

  • Использование scanf для записи в z переменную, которая также является вашей суммирующей переменной. По сути, вы перезаписываете итоговое значение каждый раз, когда считываете входные данные

  • Сканирование десятичного числа в переменную с плавающей запятой приведет к непреднамеренным результатам. Необходимо изменить scanf("%d",amp;z); на scanf("%f",amp;z);

  • Оператор printf ожидает целое число, и вы передаете указатель на значение с плавающей точкой. Поэтому нужно изменить printf("the average float is %d", z/a); на printf("the average float is %f", z/a);

  • В averageFloat функцию должна быть передана переменная y, а не возвращаемое значение scanf функции в предыдущей строке.

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

1. (голос Мегатрона) Да … Я понимаю. Теперь все так ясно.

2. Я заметил еще одну проблему, связанную с этим, когда я добавляю 2 входа, а затем ввожу 2.5 и 3.5, он возвращает 2.5, когда он должен возвращать 3.0 почему это?

3. При ближайшем рассмотрении вы также используете возвращаемое значение инструкции scanf как количество элементов для усреднения: n = scanf("%d", amp;y);averageFloat(n); . Переменная y должна использоваться в вызове averageFloat

4. Но разве y и n не должны быть здесь в основном одинаковыми, или я что-то упускаю? (Я определенно чего-то не понимаю, потому что я сделал то, что вы сказали, и это сработало должным образом.)

5. Так вот почему она продолжала возвращать 2.5, и вот почему я должен использовать y, потому что значение, которое она возвращает при присвоении, — это просто количество элементов. Я просто продолжу читать, я еще недостаточно далеко продвинулся в своей книге, но позже есть раздел о пределах scanf.

Ответ №2:

Когда вы это делаете, scanf("%f", amp;z); вы уничтожаете все, что имело значение z . Вы также не проверяете, было ли scanf выполнено успешно.

Вы должны сделать что-то вроде:

 float zz= 0.0;
scanf("%f", amp;zz); 
z  = zz;
  

Кроме того, после того, как вы закончите, вы могли бы либо сделать:

 printf("the average float is %d", (int) z/a);
return z / a;
  

Или:

 printf("the average float is %f", z/a);
return z / a; 
  

Первое усечение до int ( %d ), а второе вывод float .

Вы также должны проверить, что a не равно нулю.

Вы также должны использовать:

 averageFloat(y);
  

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

1. (int)(z/a) было бы лучше, поскольку оно сохраняет больше информации.

2. Это сработало, я выбрал метод bottom. Спасибо! 🙂 Но я не совсем понимаю, что произошло. Все, что я сделал, это объявил глобальную zz и поместил локальную переменную z внутри averageFloat . Почему это все исправило?

3. 3 вещи: во-первых, вы перезаписывали z с помощью scanf , поэтому объявление переменной только для ввода чисел — правильный способ ( zz ). Во-вторых, вы говорили ему, что собираетесь напечатать целое число ( %d ), но вы дали ему значение с плавающей точкой (результат деления, который включал значение с плавающей точкой; об этом должно быть предупреждение в любом современном компиляторе). В-третьих, n= scanf("%d", amp;y); означает: введите число, прочитанное в y , и включите индикатор успеха n , поэтому, если вы введете 3, y будет 3, а n будет 1.

4. @paxdiablo Нет. (int)(z/a) усекает дробную часть.

5.Мирко, моим намерением было отложить усечение как можно дольше, поскольку (int) z / a усекает, z затем выполняет целочисленное деление, а (int)(z/a) выполняет деление с плавающей точкой и только после этого усекает значение с плавающей точкой. Однако при тестировании я не смог придумать пример, в котором была бы разница, поскольку усечение округляется до нуля. Я подозреваю, что округление было бы другим вопросом.

Ответ №3:

Прежде всего, переменные не должны быть глобальными. Во-вторых, вы добавляете в z, а затем считываете это. И вы, вероятно, имеете в виду вызов функции averageFloat(y).