寻找热指数和风寒的计划(C计划)

时间:2017-06-10 19:57:30

标签: c

我的程序输出有问题,无法弄清楚我哪里出错了。温度似乎正确地从摄氏温度转换为华氏温度,但是当涉及风寒和热量指数值时,它们是不正确的。这让我觉得我在函数中计算它们的方式有问题吗?如果我可以得到一个解释,我的逻辑是错误的,这将是伟大的。在此先感谢,抱歉我的格式不佳!

#include <stdio.h>
#include <math.h>
#define L_Limit -20
#define U_Limit 50
#define c1 -42.379
#define c2 2.04901523
#define c3 10.14333127
#define c4 -0.22475541
#define c5 -6.83783E-3
#define c6 -5.481717E-2
#define c7 1.22874E-3
#define c8 8.5282E-4
#define c9 -1.99E-6
#define d1 35.74
#define d2 0.6125
#define d3 35.75
#define d4 0.4275

double compute_heat_index(int num1, int num2);
double compute_wind_chill(int num1, int num2);

double compute_heat_index(int num1, int num2)
{
    int celsius;
    double humid=.40;
    double celsius_f=0, heat_index=0;
    int ext1=0;
    for(celsius=1;celsius<=num2;celsius++)
    {
        printf("%d\t", celsius);
        celsius_f=(celsius*(9/5))+32;
        printf("%2.2lf\t", celsius_f);

        for(humid=.40;humid<=1;humid=humid+.10)
        {
            heat_index=c1+(c2*celsius_f)+(c3*humid)+.   (c4*humid*celsius_f)+(c5*pow(celsius,2))+(c6*pow(humid,2))+(c7*pow(celsius,2)*humid)+(c8*celsius*pow(humid,2))+(c9*pow(celsius,2)*pow(humid,2));
            if(heat_index<80)
                printf("x\t");
            else
                printf("%2.2lf/t", heat_index);
        }
        if(celsius_f>100)
        {
            ext1++;
        }
        humid=.40;
        celsius_f=0;
        heat_index=0;
    }
    return heat_index;
}

double compute_wind_chill(int num1, int num2)
{
    int celsius, wind=5;
    double celsius_f=0, wind_chill=0;
    int ext2=0;
    for(celsius=1;celsius<=num2;celsius++)
    {
        printf("%d\t", celsius);
        celsius_f=(celsius*(9/5))+32;
        printf("%lf\t", celsius_f);

        for(wind=5;wind<=40;wind=wind+5)
        {
            wind_chill=d1+(d2*celsius_f)-(d3*wind)+(d4*celsius_f*wind);
            if(wind_chill>50)
                printf("x\t");
            else 
                printf("%lf\t", wind_chill);
        }
        if(celsius_f<-20)
        {
            ext2++;
        }
        wind=5;
        celsius_f=0;
        wind_chill=0;
    }
    return wind_chill;
}
int main(void)
{
    double num1, num2;
    int ext1=0, ext2=0;

    printf("Input a range of values using two numbers:\n");
    scanf("\n%lf%lf", &num1, &num2);

    while(num1<L_Limit&&num1>U_Limit&&num2<L_Limit&&num2<U_Limit)
    {
        printf("Range of Values are Invalid!\n");
        scanf("\n%lf%lf", &num1, &num2);
    }
  printf("Celsius\tFahrenheit\t5mph\t10mph\t15mph\t20mph\t25mph\t30mph\t35mph\t40mph\n");
    compute_wind_chill(num1, num2);
    printf("\nTotal Extreme Values: %d", ext1);
    compute_heat_index(num1, num2);
    printf("\nTotal Extreme Values: %d", ext2);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

虽然我对化学计量计算的正确性没有评论(虽然我在最后提供了链接和提示),但以下内容将帮助您找到问题,不仅仅是在这里,而是希望在您编写的所有未来代码。你自己制作的东西比你需要的格式化代码更难。除非你参加比赛才能看到你可以使用的线条很少,所以为了善良,你可以通过打开&#39; 让你的代码变得更容易。这将使您和任何帮助您的人更容易遵循代码逻辑并发现逻辑错误。例如,几乎不可能发现逻辑错误:

            heat_index=c1+(c2*celsius_f)+(c3*humid)+.   (c4*humid*celsius_f)+(c5*pow(celsius,2))+(c6*pow(humid,2))+(c7*pow(celsius,2)*humid)+(c8*celsius*pow(humid,2))+(c9*pow(celsius,2)*pow(humid,2));

(当然你的编译器会大声抱怨第一行末尾的错误'.'

它的可读性更高:

            heat_index = c1 + (c2 * celsius_f) + (c3 * humid) +
                (c4 * humid * celsius_f) + (c5 * pow (celsius, 2)) +
                (c6 * pow (humid, 2)) + (c7 * pow (celsius, 2) * humid) +
                (c8 * celsius * pow (humid, 2)) +
                (c9 * pow (celsius, 2) * pow (humid, 2));

甚至:

            heat_index = c1 + 
                        (c2 * celsius_f) + 
                        (c3 * humid) +
                        (c4 * humid * celsius_f) + 
                        (c5 * pow (celsius, 2)) +
                        (c6 * pow (humid, 2)) + 
                        (c7 * pow (celsius, 2) * humid) +
                        (c8 * celsius * pow (humid, 2)) +
                        (c9 * pow (celsius, 2) * pow (humid, 2));

注意:,您可以轻松查看celsius误用celsius_f(华氏度)的情况。另请注意,pow (celsius_f, 2)不需要celsius_f * celsius_f来完成工作。

为您的输出执行相同操作。让您轻松阅读,以便其他人阅读也更容易。

(我变老了,也许你年轻的眼睛没有代码没有空格的麻烦,如果你的代码有足够的间距并且正确缩进并且你的输出看起来像其他东西那么我会更容易帮助你而不是意大利面穿过屏幕)

避免在代码中使用&#39; ,例如

    for(wind=5;wind<=40;wind=wind+5)

如果您的代码中需要常量,请根据需要声明它们。这样,只需要一个地方就可以更改价值,很容易在顶部找到,而不是通过代码来挑选它们。你已经为湿球/干球计算了大量的数据,只需要几个就可以满足你的限制,例如

#define HMIN .40    /* define needed constants */
#define HMAX 1.0    /* avoid putting 'magic'   */
#define HSTEP 0.1   /* numbers in your code    */

#define WMIN 5
#define WMAX 40
#define WSTEP 5
...
    for (wind = WMIN; wind <= WMAX; wind = wind + WSTEP)

注意:当您更正单位时,HMIN, HMAX, HSTEP值会发生变化(请参阅最后一段)。

您似乎想要从ext1ext2函数返回compute_wind_chillcompute_heat_index的值。如果是,那么您的函数type应该与您需要的return type匹配。如果您想要通过返回ext1ext2来指明是否遇到极值,那么您应该将您的函数类型更改为int并指定返回值ext1中的ext2main,例如

int compute_heat_index (int num1, int num2);
int compute_wind_chill (int num1, int num2);
...
    ext1 = compute_wind_chill (num1, num2);
    printf ("\nTotal Extreme Values: %d\n", ext1);
    ...
    ext2 = compute_heat_index (num1, num2);
    printf ("\nTotal Extreme Values: %d\n", ext2);

接下来,不需要多次拨打电话,例如printf当一个人做的时候。例如:

    printf("%d\t", celsius);
    celsius_f=(celsius*(9/5))+32;
    printf("%2.2lf\t", celsius_f);
只需通过逻辑排序printf计算,就可以轻松地将{p>替换为celsius_f次调用,例如

    celsius_f = (celsius * (9 / 5)) + 32;
    printf ("%d\t% .2lf\t", celsius, celsius_f);

为什么在num1中将num2double声明为main是一个完全的谜。您将它们作为int传递给您的函数(我假设num1应该是函数中temp的较低循环值,而不是您拥有的硬编码1 )。虽然您可以自由地允许用户输入例如45.3并将其作为double阅读,并将其作为int传递,但它并没有多大的逻辑意义。在这里,45的值就是代码中使用的所有内容。如果您正在以double阅读,以防止用户输入45.3时出现错误,那么这是合理的原因,但为什么用户宁愿输入45.3而不仅仅是{{1}另一回事......

您对小于/大于45的值的极限测试有点广告素材。最好简单地按升序排列值以简化测试,例如

L_Limit/U_Limit

格式化输出只是需要更多注意细节。虽然我不喜欢标签( /* VALIDATE all user input */ if (scanf ("%lf %lf", &num1, &num2) != 2) { fprintf (stderr, "error: invalid input.\n"); return 1; } if (num1 > num2) { /* get values in ascending order */ double tmp = num1; num1 = num2; num2 = tmp; } while (num1 < L_Limit || num2 > U_Limit) { /* simple test */ )格式化,但我已经快速尝试清理一些东西以使输出更清晰。同样,当你需要一个额外的换行符时,不要使用 variadic '\t',没有理由只输出一个字符,使用{ {1}}而是。 (注意:你不会犯这个错误,但我必须添加一个换行符,所以这里值得一提)。

编译代码时,请始终使用警告启用进行编译,例如编译字符串中的printf ("\n");。您可以添加putchar ('\n');进行一些额外的检查,并且可以施加大量额外的个别检查。最重要的是,在没有警告的情况下,在完全编译之前不要接受代码。阅读你得到的警告。编译器现在非常善于解释问题的确切位置和错误。 (你可以通过听取编译器告诉你的内容来学习很多C语言。)

您可以使用类似于以下内容的代码编译代码:

-Wall -Wextra

最后,完全放置它,您可以重新格式化代码并将上面的更改合并到以下类似的内容中,这样可以更容易地找到您的化学计量逻辑错误。我在下面的评论中提出了我的其他想法:

-pedantic

示例使用/输出

$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/windchill windchill.c

注意:在您转换为华氏度时,一个明显的错误是您的整数除法错误。您可以通过确保转换因子的浮点除法来解决这个问题:

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

#define L_Limit -20
#define U_Limit 50
#define c1 -42.379
#define c2 2.04901523
#define c3 10.14333127
#define c4 -0.22475541
#define c5 -6.83783E-3
#define c6 -5.481717E-2
#define c7 1.22874E-3
#define c8 8.5282E-4
#define c9 -1.99E-6
#define d1 35.74
#define d2 0.6125
#define d3 35.75
#define d4 0.4275

#define HMIN .40    /* define needed constants */
#define HMAX 1.0    /* avoid putting 'magic'   */
#define HSTEP 0.1   /* number in your code     */

#define WMIN 5
#define WMAX 40
#define WSTEP 5

/* you only need prototypes if you do not define your functions
 * until AFTER the code that makes use of them. Moving the 
 * definitions AFTER main() makes the prototypes make sense,
 * otherwise, just omit them...
 */
int compute_heat_index (int num1, int num2);
int compute_wind_chill (int num1, int num2);

int main (void) {

    double num1 = L_Limit - 1.0,  /* num1 & num2 should be int */
           num2 = U_Limit + 1.0;
    int ext1 = 0, ext2 = 0;

    printf ("Input a range of temps in deg. C, (e.g. t1 t2): ");

    /* VALIDATE all user input */
    if (scanf ("%lf %lf", &num1, &num2) != 2) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    if (num1 > num2) {      /* get values in ascending order */
        double tmp = num1;
        num1 = num2;
        num2 = tmp;
    }

    while (num1 < L_Limit || num2 > U_Limit) {  /* simple test */
        fprintf (stderr, "error: values must be between %d - %d.\n",
                L_Limit, U_Limit);
        printf ("Input a range of temps in deg. C, (e.g. t1 t2): ");
        if (scanf ("%lf %lf", &num1, &num2) != 2) {
            fprintf (stderr, "error: invalid input.\n");
            return 1;
        }
    }

    /* make the output format easy to read */
    printf ("\nDeg. C\t Deg. F\t 5mph\t 10mph\t 15mph\t"
            " 20mph\t 25mph\t 30mph\t 35mph\t 40mph\n");
    ext1 = compute_wind_chill (num1, num2);
    printf ("\nTotal Extreme Values: %d\n", ext1);

    printf ("\nDeg. C\t Deg. F\t 40%%\t 50%%\t 60%%\t"
            " 70%%\t 80%%\t 90%%\t 100%%\n");
    ext2 = compute_heat_index (num1, num2);
    printf ("\nTotal Extreme Values: %d\n", ext2);

    return 0;
}

/* comput and output heat index between num1 and num2 */
int compute_heat_index (int num1, int num2)
{
    int celsius, ext1 = 0;
    double humid = HMIN, celsius_f = 0, heat_index = 0;

    for (celsius = num1; celsius <= num2; celsius++) 
    {
        celsius_f = (celsius * (9 / 5)) + 32;
        printf ("%d\t% .2lf\t", celsius, celsius_f);

        for (humid = HMIN; humid <= HMAX; humid = humid + HSTEP) 
        {
            heat_index = c1 + (c2 * celsius_f) + (c3 * humid) +
                (c4 * humid * celsius_f) + (c5 * pow (celsius, 2)) +
                (c6 * pow (humid, 2)) + (c7 * pow (celsius, 2) * humid) +
                (c8 * celsius * pow (humid, 2)) +
                (c9 * pow (celsius, 2) * pow (humid, 2));

            if (heat_index < 80)
                printf ("x\t");
            else
                printf ("% .2lf\t", heat_index);
        }
        putchar ('\n');

        if (celsius_f > 100) {
            ext1++;
        }
    }

    return ext1;
}

/* comput and output wind chill between num1 and num2 */
int compute_wind_chill (int num1, int num2)
{
    int celsius, wind = WMIN, ext2 = 0;
    double celsius_f = 0, wind_chill = 0;

    for (celsius = num1; celsius <= num2; celsius++) 
    {
        celsius_f = (celsius * (9 / 5)) + 32;
        printf ("%d\t% .2lf\t", celsius, celsius_f);

        for (wind = WMIN; wind <= WMAX; wind = wind + WSTEP) 
        {
            wind_chill = d1 + (d2 * celsius_f) - (d3 * wind) + 
                        (d4 * celsius_f * wind);

            if (wind_chill > 50)
                printf (" x\t");
            else
                printf ("% .2lf\t", wind_chill);
        }
        putchar ('\n');

        if (celsius_f < -20) {
            ext2++;
        }
    }

    return ext2;
}

进行一次更改将对您的计算产生巨大影响,例如

$ ./bin/windchill
Input a range of temps in deg. C, (e.g. t1 t2): 45 55
error: values must be between -20 - 50.
Input a range of temps in deg. C, (e.g. t1 t2): 45 50

Deg. C   Deg. F  5mph    10mph   15mph   20mph   25mph   30mph   35mph   40mph
45       77.00   x       x       40.41   26.25   12.09  -2.07   -16.23  -30.40
46       78.00   x       x       47.44   35.42   23.39   11.37  -0.66   -12.68
47       79.00   x       x       x       44.58   34.69   24.80   14.92   5.03
48       80.00   x       x       x       x       45.99   38.24   30.49   22.74
49       81.00   x       x       x       x       x       x       46.07   40.45
50       82.00   x       x       x       x       x       x       x       x

Total Extreme Values: 0

Deg. C   Deg. F  40%     50%     60%     70%     80%     90%     100%
45       77.00   99.68   99.21   98.74   98.27   97.80   97.32   96.85
46       78.00   101.06  100.58  100.10  99.61   99.13   98.65   98.17
47       79.00   102.43  101.93  101.44  100.95  100.46  99.96   99.47
48       80.00   103.78  103.28  102.78  102.27  101.77  101.27  100.76
49       81.00   105.13  104.61  104.10  103.59  103.07  102.56  102.04
50       82.00   106.46  105.93  105.41  104.89  104.36  103.84  103.31

Total Extreme Values: 0

你还有一些工作要做......你可以先回顾The Heat Index Equation(这似乎是你的常数来自哪里 - 但请注意你缺少修正因子,你需要请注意湿度的单位。然后通过查看Wind Chill wind 上的 exponent 进行小心关注来跟进。当您更正公式时,您将需要链接数学库,因此将celsius_f = (celsius * (9.0 / 5)) + 32; 添加到您的编译字符串。 (那个小 - $ ./bin/windchill Input a range of temps in deg. C, (e.g. t1 t2): 45 50 Deg. C Deg. F 5mph 10mph 15mph 20mph 25mph 30mph 35mph 40mph 45 113.00 x x x x x x x x 46 114.80 x x x x x x x x 47 116.60 x x x x x x x x 48 118.40 x x x x x x x x 49 120.20 x x x x x x x x 50 122.00 x x x x x x x x Total Extreme Values: 0 Deg. C Deg. F 40% 50% 60% 70% 80% 90% 100% 45 113.00 170.20 168.93 167.65 166.37 165.09 163.81 162.53 46 114.80 173.15 171.84 170.54 169.23 167.92 166.61 165.30 47 116.60 176.09 174.75 173.42 172.08 170.74 169.40 168.06 48 118.40 179.01 177.65 176.28 174.92 173.55 172.18 170.81 49 120.20 181.92 180.53 179.14 177.74 176.35 174.95 173.56 50 122.00 184.82 183.40 181.98 180.55 179.13 177.71 176.28 Total Extreme Values: 0 m)。一旦你纠正了逻辑,你应该看到类似于以下输出的东西。

(注意:在-lm的温度范围内使用极值,我得到'L' wind_chill极值和-20 to 50 heat_index极值)

164

仔细看看,如果您有其他问题,请告诉我。

答案 1 :(得分:0)

看这里:

celsius_f=(celsius*(9/5))+32;

在C 9/5中,不等于实数中的9/5,这里整数除以整数也等于整数,四舍五入到较低的值。所以这里9/5等于1,而不是1.8。您应该使用float变量类型,例如

celsius_f=(celsius*(9.0/5))+32;

另一个错误在于:

compute_wind_chill(num1, num2);
printf("\nTotal Extreme Values: %d", ext1);

您将浮点结果显示为整数。