1.2 变量与算数表达式
下边的程序使用公式 ℃=(5/9)(℉-32)
打印华氏温度与摄氏温度对照表
#include <stdio.h>
/* 当 fahr=0,20,… ,300 时,分别
打印华氏温度与摄氏温度对照表 */
main()
{
int fahr, celsius;
int lower, upper, step;
lower = 0; /* 温度表的下限 */
upper = 300; /* 温度表的上限 */
step = 20; /* 步长 */
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
}
[vagrant@node01 1.2]$ gcc -o test test.c
[vagrant@node01 1.2]$ ls
test test.c
[vagrant@node01 1.2]$ ./test
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
下边的部分被称为注释:
/*当 fahr=0,20,… ,300 时,分别
打印华氏温度与摄氏温度对照表 */
包含在 /*
与 */
之间的字符序列将被编译器忽略
注释可以自由地运用在程序中,使得程序更易于理解
程序中允许出现空格、制表符或换行符之处,都可以使用注释
在 C 语言中,所有变量都必须先声明后使用
声明通常放在函数起始处,在任何可执行语句之前
声明用于说明变量的属性,它由一个类型名和一个变量表组成,例如:
int fahr, celsius;
int lower, upper, step;
类型 int 表示其后所列变量为整数,与之相对应的,float 表示所列变量为浮点数(即:可以带有小数部分的数)
int 与 float 类型的取值范围取决于具体的机器
对于 int 类型,通常为 16 位,其取值范围在 -32768~32767 之间
也有用 32 位表示的 int 类型
float 类型通常是 32 位,至少有 6 位有效数字,取值范围一般在 10-38~1038 之间
除 int 和 float 类型之外,C 语言还提供了其它一些基本数据类型,如:
- char 字符(一个字节)
- short 短整型
- long 长整型
- double 双精度浮点型
这些数据类型对象的大小也取决于具体的机器
另外,还存在这些基本数据类型的数组、结构、联合
指向这些类型的指针以及返回这些类型值的函教
下边四句为赋值语句,为变量设置初始值
每条语句都以分号结束:
lower = 0;
upper = 300;
step = 20;
fahr = lower;
温度转换表中的各行计算方式相同,因此可以用 while 循环语句重复输出各行:
while (fahr <= upper) {
...
}
while 循环语句的执行方式:
首先测试圆括号中的条件
如果条件为真(fahr <= upper 时),则执行循环体(括在花括号中的 3 条语句)
然后再重新测试圆括号中的条件,如果为真,则再次执行循环体
当圆括号中的条件测试结果为假时(fahr > upper 时),循环结束
然后继续执行跟在 while 循环语句之后的下一条语句
while 语句的循环体可以是用花括号括起来的一条或多条语句
也可以是不用花括号的单条语句,例如:
while (i < j)
i = 2 * i;
在这两种情况下,我们总是把由 while 控制的语句缩进一个制表位
这样可以很容易地看出循环语句中包含哪些语句
这种缩进方式突出了程序的逻辑结构
尽管 C 编译器并不关心程序的外观形式,但正确的缩进以及保留适当空格的程序设计风格对程序的易读性非常重要
我们建议每行只书写一条语句,并在运算符两边各加上一个空格字符
这样可以使得运算的结合关系更清楚明了
相比而言,花括号的位置就不那么重要了
我们从比较流行的一些风格中选择了一种
读者可以选择适合自己的一种风格,并养成一直使用这种风格的好习惯
在该程序中,绝大部分工作都是在循环体中完成的
循环体中的赋值语句 celsius = 5 * (fahr - 32) / 9
计算与指定华氏温度相对应的摄氏温度值,并将结果赋值给变量 celsius
这里需要先乘 5 然后再除以 9 而不是直接写成 5 / 9
因为在 C 语言及许多其它语言中,整数除法操作将执行舍位,结果中的任何小数部分都会被舍弃
由于 5 和 9 都是整数,5 / 9 相除后经截取所得的结果为 0
因此这样求得的所有摄氏温度都将为 0
从该例子中也可以看出 printf 函数的一些功能
printf 是一个通用输出格式化函数
该函数的第一个参数是待打印的字符串,其中的每个百分号 %
表示用其它的参数(参数 2、参数 3、…)之一进行替换的位置,并指定打印格式
它们在数目和类型上都必须匹配,否则将出现错误的结果
例如,%d 指定一个整型参数
因此语句 printf(" %d\t%d\n", fahr, celsius)
用于打印两个整数 fahr 与 celsius 的值,并在两者之间打印一个制表符 \t
printf 函数并不是 C 语言本身的一部分,C 语言本身并没有定义输入/输出功能
printf 仅仅是标准库函数中一个有用的函数而已,这些标准序函数在 C 语言程序中通常都可以使用
ANSI 标准定义了 printf 函数的行为,因此对每个符合该标准的编译器和库来说,该函数的属性都是相同的
如果在 printf 语句的第一个参数的 %d
中指明打印宽度,则打印的数字会在打印区域内右对齐
例如,可以用语句 printf(" %3d %6d\n", fahr, celsius);
:
0 -17
20 -6
40 4
60 15
80 26
100 37
...
为了得到更精确的结果,应该用浮点算术运算代替上面的整型算术运算,新版程序:
#include <stdio.h>
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300; floating-point version */
main()
{
float fahr, celsius;
float 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;
}
}
[vagrant@node01 1.2]$ gcc -o test02 test02.c
[vagrant@node01 1.2]$ ls
test01.c test02 test02.c
[vagrant@node01 1.2]$ ./test02
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
在前一个程序中,之所以不能使用 5 / 9 的形式
是因为按整型除法的计算规则,它们相除并舍位后得到的结果为 0
但是,常数中的小数点表明该常数是一个浮点数,因此,5.0 / 9.0 是两个浮点数相除,结果将不被舍位
如果某个算术运算符的所有操作数均为整型,则执行整型运算
但是,如果某个算术运算符有一个浮点型操作数和一个整型操作数,则在开始运算之前整型操作数将会被转换为浮点型
例如,在表达式 fahr – 32
中,32
在运算过程中将被自动转换为浮点数再参与运算
尽管浮点常量取的是整型值,在书写时最好还是为它加上一个显式的小数点,这样可以强调其浮点性质,便于阅读,因此上边写为 fahr - 32.0
printf 中的转换说明
%3.0f
按照浮点数打印,至少占 3 个字符宽,且不带小数点和小数部分
%.2f
指定待打印的浮点数的小数点后有两位小数,但宽度没有限制
%d
按照十进制整型数打印
%6d
按照十进制整型数打印,至少 6 个字符宽
%f
按照浮点数打印
%6f
按照浮点数打印,至少 6 个字符宽
%.2f
按照浮点数打印,小数点后有两位小数
%6.2f
按照浮点数打印,至少 6 个字符宽,小数点后有两位小数
%o
表示八进制数
%x
表示十六进制数
%c
表示字符
%s
表示字符串
%%
表示百分号 %
本身
如未指定小数点位数,则保留了 6 位小数
未超出最小字符数时右对齐,超出最小字符数时左对齐
例如将 printf("%3.0f %6.1f\n", fahr, celsius);
改为 printf("%3.0f %6f\n", fahr, celsius);
后:
[vagrant@node01 1.2]$ gcc -o test02 test02.c
[vagrant@node01 1.2]$ ./test02
0 -17.777779
20 -6.666667
40 4.444445
60 15.555555
80 26.666666
100 37.777779
120 48.888889
140 60.000000
160 71.111115
180 82.222221
200 93.333336
220 104.444443
240 115.555557
260 126.666664
280 137.777771
300 148.888885