c - 查找热量指数和冷风的程序(C程序)

标签 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;
}

最佳答案

尽管我没有对您的化学计量计算的正确性发表任何评论(尽管我在末尾提供了链接和提示),但以下内容不仅可以在这里,而且希望在以后编写的所有代码中都可以帮助您发现问题。您正在通过自己格式化代码的方式使事情变得更加棘手。除非您参加竞赛以查看可以使用的行数,否则,出于善意,请稍微“开放”您的代码,使事情变得更轻松。这将使您和任何帮助您的人更容易遵循代码的逻辑并查找逻辑错误。例如,几乎不可能发现以下逻辑错误:

            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将完成任务。

对您的输出执行相同的操作。使您易于阅读,其他人也将更容易阅读。

(我正在变老,也许您的年轻眼睛对没有空格的代码没有问题,如果您的代码有足够的间距和适当的缩进,并且输出看起来像是意大利面条以外的其他东西,那么帮助我就容易得多了。屏幕)

避免在代码中使用“幻数”,例如

    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计算进行排序即可轻松地将其替换为单个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而不是仅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 */


格式化输出只是需要更多注意细节的事情。尽管我不喜欢制表符('\t')格式,但我已进行了一些尝试,以使输出内容更清晰。同样,当您需要其他换行符时,请不要使用可变参数printf ("\n");,也没有理由仅输出一个字符而使用开销,而应使用putchar ('\n');。 (注意:您不会犯此错误,但是我必须添加一个换行符,因此在这里值得一提)。

编译代码时,请始终在启用警告的情况下进行编译,例如您的编译字符串中的-Wall -Wextra。您可以添加-pedantic进行一些其他检查,并且可以施加许多其他个人检查。最重要的是,在没有警告的情况下将代码干净地编译之前,不要接受代码。阅读得到的警告。现在,编译器非常擅长于准确说明问题出在哪里以及您在做什么错。 (通过听编译器告诉您的内容,您可以学到很多C语言)。

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

$ 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


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

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


您还有更多工作要做...您可以从查看The Heat Index Equation开始(这似乎是常量的来源-但请注意,您缺少校正因子,需要特别注意湿度的单位) )。然后通过观察Wind Chill进行后续操作,并仔细注意风中的指数。纠正公式后,您将需要链接数学库,因此请将-lm添加到编译字符串中。 (很小-'L' m)。纠正逻辑后,您应该会看到类似于以下输出的内容。

(注意:在温度范围为-20 to 50的极端值下,我得到164 wind_chill极端和332 heat_index极端)

$ ./bin/windchill
Input a range of temps in deg. C, (e.g. t1 t2): 10 45

Wind Chill:

Deg. C   Deg. F  5mph    10mph   15mph   20mph   25mph   30mph   35mph   40mph
10       50.00   47.77   45.59   44.19   43.15   42.31   41.59   40.98   40.43
11       51.80   49.87   47.80   46.48   45.50   44.70   44.02   43.44   42.92
12       53.60   51.96   50.02   48.77   47.84   47.09   46.45   45.90   45.41
13       55.40   54.06   52.23   51.06   50.19   49.48   48.88   48.36   47.90
14       57.20   56.16   54.45   53.35   52.53   51.87   51.31   50.82   50.39
15       59.00   58.26   56.66   55.64   54.88   54.26   53.74   53.28   52.88
16       60.80   60.36   58.88   57.93   57.22   56.65   56.16   55.74   55.37
17       62.60   62.45   61.09   60.22   59.57   59.04   58.59   58.21   57.86
18       64.40   x       63.30   62.51   61.91   61.43   61.02   60.67   60.35
19       66.20   x       65.52   64.80   64.26   63.82   63.45   63.13   62.85
20       68.00   x       67.73   67.09   66.60   66.21   65.88   65.59   65.34
21       69.80   x       x       69.38   68.95   68.60   68.31   68.05   67.83
22       71.60   x       x       x       71.29   70.99   70.74   70.51   70.32
23       73.40   x       x       x       x       73.38   73.16   72.98   72.81
24       75.20   x       x       x       x       x       x       x       x
...

Total Extreme Values: 0

Heat Index:

Deg. C   Deg. F  40%     50%     60%     70%     80%     90%     100%
...
26       78.80   x       x       x       x       x       x       x
27       80.60   80.35   81.35   82.55   83.94   85.53   87.32   89.31
28       82.40   81.80   83.21   85.01   87.20   89.78   92.75   96.10
29       84.20   83.49   85.39   87.86   90.91   94.53   98.74   103.51
30       86.00   85.44   87.89   91.10   95.07   99.80   105.29  111.55
31       87.80   87.64   90.71   94.72   99.68   105.58  112.42  120.21
32       89.60   90.10   93.85   98.73   104.74  111.86  120.11  129.49
33       91.40   92.81   97.32   103.13  110.25  118.66  128.38  139.39
34       93.20   95.77   101.11  107.92  116.20  125.97  137.21  149.92
35       95.00   98.99   105.22  113.09  122.61  133.78  146.60  161.07
36       96.80   102.46  109.65  118.65  129.47  142.11  156.57  172.84
37       98.60   106.18  114.40  124.60  136.78  150.95  167.10  185.24
38       100.40  110.16  119.47  130.93  144.54  160.30  178.20  198.26
39       102.20  114.39  124.87  137.65  152.75  170.15  189.87  211.90
40       104.00  118.88  130.58  144.76  161.40  180.52  202.11  226.17
41       105.80  123.62  136.62  152.25  170.51  191.40  214.91  241.05
42       107.60  128.61  142.98  160.13  180.07  202.79  228.28  256.56
43       109.40  133.85  149.66  168.40  190.08  214.68  242.22  272.70
44       111.20  139.35  156.66  177.06  200.53  227.09  256.73  289.45
45       113.00  145.10  163.99  186.10  211.44  240.01  271.81  306.83

Total Extreme Values: 97


仔细检查一下,如果您还有其他问题,请告诉我。

关于c - 查找热量指数和冷风的程序(C程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44477510/

相关文章:

在数组中收集相同的单词,C

c - 共享内存程序行为异常

c - getopt 给出 -1 作为返回值

C:按顺序计算 2 个表达式,然后返回第一个

c - C 程序的内存段

c++ - Windows 与 fork() 最接近的东西是什么?

在二进制搜索中计算中点索引

c - 通过管道向子进程写入和读取不起作用

objective-c - 将字符串添加到数组

CS50 pset5 哈希表节点