fahr.c
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300 */
int main(void)
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* lower limit of temperature scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr - 32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
$ cc -g -O0 -Wall -o a.out fahr.c
$ ./a.out
0 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Причина, по которой мы сначала умножаем на 5 и затем делим на 9, а не сразу умножаем на 5/9, связана с тем, что в Си деление целых сопровождается отбрасыванием, т. е. потерей дробной части. Так как 5 и 9 - целые, отбрасывание в 5/9 дало бы нуль, и на месте температур по Цельсию были бы напечатаны нули.
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300 */
int main(void)
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* lower limit of temperature scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = 5 / 9 * (fahr - 32);
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
$ cc -g -O0 -Wall -o a.out fahr.c
$ ./a.out
0 0
20 0
40 0
60 0
80 0
100 0
120 0
140 0
160 0
180 0
200 0
220 0
240 0
260 0
280 0
300 0
Существуют еще две проблемы, связанные с программой преобразования температур. Одна из них (более простая) состоит в том, что выводимый результат выглядит несколько неряшливо, поскольку числа не выровнены по правой позиции колонок. Это легко исправить, добавив в каждый из спецификаторов формата %d указание о ширине поля; при этом программа будет печатать числа, прижимая их к правому краю указанных полей. Например, мы можем написать
чтобы в каждой строке первое число печатать в поле из трех позиций, а второе - из шести.
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300 */
int main(void)
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* lower limit of temperature scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr - 32) / 9;
printf("%3d\t%6d\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
$ cc -g -O0 -Wall -o a.out fahr.c
$ ./a.out
0 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Вторая, более серьезная проблема связана с тем, что мы пользуемся целочисленной арифметикой и поэтому не совсем точно вычисляем температуры по шкале Цельсия. Например, 0°F на самом деле (с точностью до десятой) равно -17.8 °С, а не -17. Чтобы получить более точные значения температур, нам надо пользоваться не целочисленной арифметикой, а арифметикой с плавающей точкой. Это потребует некоторых изменений в программе.
fahr2.c
#include <stdio.h>
/* print Fahrenheit-Celsius table
* for fahr = 0, 20, ..., 300; floating-point version */
int main(void)
{
float fahr, celsius;
int lower, upper, step;
lower = 0; /* lower limit of temperatuire scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper)
{
celsius = (5.0 / 9.0) * (fahr - 32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
$ cc -g -O0 -Wall -o a.out fahr2.c
$ ./a.out
0 -17.8
20 -6.7
40 4.4
60 15.6
80 26.7
100 37.8
120 48.9
140 60.0
160 71.1
180 82.2
200 93.3
220 104.4
240 115.6
260 126.7
280 137.8
300 148.9