查找热指数和风寒的程序(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("%dt", celsius);
celsius_f=(celsius*(9/5))+32;
printf("%2.2lft", 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("xt");
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("%dt", celsius);
celsius_f=(celsius*(9/5))+32;
printf("%lft", 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("xt");
else 
printf("%lft", 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("CelsiustFahrenheitt5mpht10mpht15mpht20mpht25mpht30mpht35mpht40mphn");
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值会发生变化(请参阅最后一段)。

您似乎想要从compute_wind_chillcompute_heat_index函数中返回ext1ext2的值。如果是这样,那么您的函数type应该与所需的return type相匹配。如果你想指示是否通过返回ext1ext2遇到极值,那么你应该将函数类型更改为int,并将返回分配给ext1main中的ext2,例如

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: %dn", ext1);
...
ext2 = compute_heat_index (num1, num2);
printf ("nTotal Extreme Values: %dn", ext2);

接下来,无需多次调用,例如printf什么时候会做。例如:

printf("%dt", celsius);
celsius_f=(celsius*(9/5))+32;
printf("%2.2lft", celsius_f);

只需对celsius_f计算进行逻辑排序,即可轻松替换为单个printf调用,例如

celsius_f = (celsius * (9 / 5)) + 32;
printf ("%dt% .2lft", celsius, celsius_f);

为什么你宣布num1num2maindouble是一个完全的谜。您可以将它们作为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. Ct Deg. Ft 5mpht 10mpht 15mpht"
" 20mpht 25mpht 30mpht 35mpht 40mphn");
ext1 = compute_wind_chill (num1, num2);
printf ("nTotal Extreme Values: %dn", ext1);
printf ("nDeg. Ct Deg. Ft 40%%t 50%%t 60%%t"
" 70%%t 80%%t 90%%t 100%%n");
ext2 = compute_heat_index (num1, num2);
printf ("nTotal Extreme Values: %dn", 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 ("%dt% .2lft", 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 ("xt");
else
printf ("% .2lft", 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 ("%dt% .2lft", 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 (" xt");
else
printf ("% .2lft", 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

你还有一些工作要做...您可以从查看热指数方程开始(这似乎是常数的来源 - 但请注意您缺少校正因子,您需要仔细注意湿度单位)。然后跟进看风仔细注意指数。更正公式时,需要链接到数学库,因此请将-lm添加到编译字符串中。(那是小 -'L'm)。更正逻辑后,应会看到类似于以下输出的内容。

(注意:在温度范围内,极值从-20 to 50,我得到164wind_chill极端和332heat_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

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

看这里:

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);

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

最新更新