Программа всегда выводит значение 0

#include <stdio.h>
void volume()
{
   float pi=3.14,r,v;
   printf("\nEnter the radius: ");
   scanf("%f",&r);
   v=(1/3)*pi*r*r*r;
   printf("%f",v);
}
int main()
{
   volume();

}

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

Подсказка: компилируйте с предупреждениями на самом высоком уровне. Спецификатор формата в scanf недействителен.

Sergey Kalinichenko 11.08.2018 02:55
(1/3) - это целое число, равное 0. замените его на (1.0 / 3.0).
bruceg 11.08.2018 02:56

Есть чтение float, а 1/3 - это подразделение int. Вместо этого используйте pi*r*r*r/3.

Sergey Kalinichenko 11.08.2018 02:56
c-faq.com/expr/truncation1.html
melpomene 11.08.2018 03:01
Стоит ли изучать 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
4
126
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

у вас здесь ноль из-за того, что 1/3 - это целочисленное деление = 0

заменить v=(1/3)*pi*r*r*r; на v=(1.f/3.f)*pi*r*r*r;

Это потому, что все, что умножено на 0, - это 0, а 1/3 - это 0.

1/3 - это 0, потому что и 1, и 3 являются литералами типа int, и деление двух целых чисел снова дает целое число.

Исправление: 1.0/3.0, потому что 1.0 и 3.0 являются литералами с плавающей запятой, поэтому вы получаете деление с плавающей запятой.

Разве это не сработает, если вы просто зафиксируете только числитель или знаменатель? то есть 1/3.0?

Andy J 11.08.2018 06:56

@AndyJ Да, тогда другой операнд будет неявно преобразован в double, но я предпочитаю быть явным.

melpomene 11.08.2018 13:16
Ответ принят как подходящий

Поскольку 1/3 не равно 0,3333 в C, это 0.

Решение:

#include <stdio.h>
void volume()
{
   float pi=3.14,r,v;
   printf("\nEnter the radius: ");
   scanf("%f",&r);
   v=(((float)1)/3)*pi*r*r*r;
   printf("%f",v);
}
int main()
{
   volume();

} 

Почему вы взяли (float), есть ли разница? и какой от этого толк?

user10016836 11.08.2018 03:22

@Avi Прочтите о приведении типов в своем учебнике или руководстве по C.

Barmar 11.08.2018 03:38

Это связано с тем, что 1 / 3 выполняется как целочисленное деление, потому что оба операнда относятся к типу int(a). Так что конечный результат нулевой.

Вы можете получить желаемый эффект, просто убедившись, что один из операндов не является целым числом, например:

v = (1.0f / 3) * pi * r * r * r;

Это сработает, потому что в результате получается число 0.333... с плавающей запятой (в круглых скобках). Однако есть абсолютно реальная причина, по которой вам нужно повторять уравнение, показанное в учебниках, вы можете добиться того же результата с помощью более простого:

v = pi * r * r * r / 3;

Поскольку все эти переменные являются с плавающей запятой, результатом последнего something / 3 будет также, выполненный как с плавающей запятой.


И, просто небольшой совет, вы, май, хотите рассмотреть возможность использования типов double, а не float. Тип float обычно использует меньше места, но, если у вас нет больших массивов, это обычно не проблема. Тип double обеспечивает гораздо больший диапазон и точность.


Кроме того, 3.14 на самом деле не является точным значением тот для pi. Большинство реализаций будут определять константу M_PI в math.h, которую вы можете использовать, но это не предусмотрено стандартом. Итак, вы можете использовать что-то вроде этого, чтобы получить более точное значение:

#include <stdio.h>
#include <math.h>

// Define if implementation doesn't provide.

#ifndef M_PI
    #define M_PI 3.14159265358979323846
#endif

static void GetRadiusAndPrintVolume(void) {
    printf("\nEnter the radius: ");
    double radius;
    scanf("%lf", &radius);

    double volume = M_PI * radius * radius * radius / 3;

    printf("Volume for radius %f is %f\n", radius, volume);
}

int main() {
    GetRadiusAndPrintVolume();
}

И, наконец, вы, май, хотите проверить свое уравнение. Хотя вы не говорите явно, это очень похоже на выглядит, как будто это должен быть объем сферы.

Если это является, формула должна быть 4/3 π r3, а не 1/3. Следовательно, утверждение было бы таким:

double volume = M_PI * radius * radius * radius * 4 / 3;

(a) Если вам интересно, все это описано в разделе «Обычные арифметические преобразования» стандарта C (раздел 6.3.1.8 в C11):

Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result.

Затем он переходит к перечислению того, что происходит в конкретных случаях, а именно: «меньший» (с точки зрения диапазона и / или точности) операнд обновляется до того же типа, что и «больший» операнд. Это основная идея, если вам нужна картинка полный, вам следует обратиться к ранее упомянутому разделу.

В конкретном случае ваш, поскольку оба операнда 1 / 3 относятся к типу int, вычисление и результат выполняются как int, то есть дробная часть усекается (дается ноль).

И если это не было сказано, запоздалые поздравления с 600-тысячной маркой :), вы, Леффлер и Дэш, загнали рынок в угол ...

David C. Rankin 11.08.2018 03:27

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