【问题标题】:BMI calculator C code [closed]BMI计算器C代码[关闭]
【发布时间】:2016-02-12 10:13:45
【问题描述】:

我正在尝试编写一个简单的 BMI 计算器,但由于某种原因,当我尝试身高 175(公式为 1.75)和体重 70 时,它应该给出 22.8,这在健康范围内,但它给出我体重过轻。我知道这可能是一个简单的错误,但我看不到。

float main(void) { 

    float height;   
    printf("Enter your height in cm:\n");
    scanf("%f",&height);    

    float weight; 
    printf("Enter your weight in kg:\n");
    scanf("%f",&weight);

    float bmi;
    bmi = (weight/(height/100)*(height/100));

    if (bmi <= 16) {
        printf("Severely Underweight\n");
    }
    else if (16 < bmi <= 18.5) {
        printf("Underweight\n");
    }
    else if (18.5 < bmi <= 25) {
        printf("Healthy\n");
    }
    else if (25 < bmi <= 30) {
        printf("Overweight\n");
    }
    else {
        printf("Severely Overweight\n");
    }
}

【问题讨论】:

  • Bathsheba 有,但你一开始不需要复合条件,因为条件发生在else ifs 中,下限已经确定。
  • 哦,请从main返回int,而不是float
  • C 和 C++ 都不支持这样的运算符链接。将条件一分为二,用逻辑 AND 运算符分隔以获得所需的结果。
  • 我喜欢总是说我没有超重的体重指数计算器。编译并发布!
  • 更糟糕的是,它总是说我超级肥胖,因为计算不正确:假设的分母相互抵消,结果就是以公斤为单位的重量。 (有趣的是,公式使用了很多括号,却漏掉了分母周围唯一重要的一对。)

标签: c++ c if-statement math indexing


【解决方案1】:

所有这些

else if (16 < bmi <= 18.5) {

错了。他们不会做你想让他们做的事。要达到预期的结果,请使用

else if (16 < bmi && bmi <= 18.5) {

原因是,你的表达式被评估为

else if ((16 < bmi) <= 18.5) {

其中(16 &lt; bmi) 的计算结果为truefalse,后者又等于10,然后与第二个常数进行比较。之所以这样评估,是因为比较运算符是left-associative,因此是从左到右评估的。

编辑 2

必填 SO 链接:Is (4 > y > 1) a valid statement in C++? How do you evaluate it if so?

编辑

我怀疑这个,但不知道公式。现在@MOehm 已经证实了这一点(维基百科似乎也证实了这一点):

bmi = (weight/(height/100)*(height/100));

应该变成

bmi = (weight/((height/100)*(height/100)));

这里的原因几乎相同:C++ 中的运算符优先级和表达式求值规则。 OP,注意这些方面,并在适当的地方加上括号!

编辑 3 以下是我将如何使用 STL 来解决此问题(这种方法的好处是可以清楚地表达算法背后的想法,而不会将其隐藏在实现细节之下):

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <limits>
#include <algorithm>

int main()
{
    std::vector<std::pair<float, std::string> > bmi_table = {
        { 16, "Severely Underweight" },
        { 18.5, "Underweight" },
        { 25, "Healthy" },
        { 30, "Overweight" },
        { std::numeric_limits<float>::max(), "Severely Overweight" }
    };
    float height, weight;
    std::cin >>  height >> weight;
    const float bmi = (weight/((height/100.f)*(height/100.f)));
    const auto idx =
        std::find_if(bmi_table.begin(),
                     bmi_table.end(),
                     [&](decltype(bmi_table)::value_type& p) -> bool { return p.first > bmi; });
    std::cout << idx->second << '\n';
    return 0;
}

【讨论】:

  • 由于 OP 的多标记,我故意在回答中毛骨悚然。在 C 中,关系运算符的值为 1 和 0,它们是 int 类型。在 C++ 中,它们是 truefalse 并且是 bool 类型。这些是在“链接”运算符时可能相关的微小但重要的区别。
  • 很遗憾,我不太了解 C。但是,bools 不是在 C++ 中隐式转换为 int 的吗?
  • 这取决于周围的环境。
  • 关于这个主题有什么我应该在答案中更正的吗?很乐意这样做。
  • 谢谢你,你已经超越了自己的问题和我的要求。
【解决方案2】:

16 &lt; bmi &lt;= 18.5 并没有做你认为它做的事情,例如。 (虽然它可以编译,但它实际上被评估为(16 &lt; bmi) &lt;= 18.5,括号中的位是 1(真)或 0(假)。)

你需要写16 &lt; bmi &amp;&amp; bmi &lt;= 18.5

但如果您订购 bmi 限制,则无需重复测试下限。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    相关资源
    最近更新 更多