详解C语言中的符号常量、变量与算术表达式

C语言中的符号常量
在结束讨论温度转换程序前,我们再来看一下符号常量。在程序中使用 300、20 等类似的“幻数”并不是一个好习惯,它们几乎无法向以后阅读该程序的人提供什么信息,而且使程序的修改变得更加困难。处理这种幻数的一种方法是赋予它们有意义的名字。#define 指令可以把符号名(或称为符号常量)定义为一个特定的字符串:

#define 名字 替换文本

在该定义之后,程序中出现的所有在 #define 中定义的名字(既没有用引号引起来,也不是其它名字的一部分)都将用相应的替换文本替换。其中,名字与普通变量名的形式相同:它们都是以字母打头的字母和数字序列;替换文本可以是任何字符序列,而不仅限于数字。
在该定义之后,程序中出现的所有在 #define 中定义的名字(既没有用引号引起来,也不是其它名字的一部分)都将用相应的替换文本替换。其中,名字与普通变量名的形式相同:它们都是以字母打头的字母和数字序列;替换文本可以是任何字符序列,而不仅限于数字。

#include <stdio.h>

#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */

/* print Fahrenheit-Celsius table */
main()
{
 int fahr;
 for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
 printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

其中,LOWER、UPPER 与 STEP 都是符号常量,而非变量,因此不需要出现在声明中。符号常量名通常用大写字母拼写,这样可以很容易与用小写字母拼写的变量名相区别。注意,#define 指令行的末尾没有分号。

变量与算术表达式
我们来看下一个程序,使用公式℃=(5/9)(℉-32)打印下列华氏温度与摄氏温度对照表:

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

此程序中仍然只包括一个名为 main 的函数定义。它比前面打印“hello, world”的程序长一些,但并不复杂。这个程序中引入了一些新的概念,包括注释、声明、变量、算术表达式、循环以及格式化输出。该程序如下所示:

#include <stdio.h>
/* 当 fahr=0,20,… ,300 时,分别打印华氏温度与摄氏温度对照表 */
main()
{
 int i;
 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;
 }
 scanf("%s", &i);
}

其中的一行:

/*当 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:双精度浮点型

这些数据类型对象的大小也取决于具体的机器。另外,还存在这些基本数据类型的数组、结构、联合,指向这些类型的指针以及返回这些类型值的函教。

在上面的温度转换程序中,最开始执行的计算是下列 4 个赋值语句:

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 编译器并不关心程序的外观形式,但正确的缩进以及保留适当空格的程序设计风格对程序的易读性非常重要。我们建议每行只书写一条语句,并在运算符两边各加上一个空格字符,这样可以使得运算的结合关系更清楚明了。相比而言,花括号的位置就不那么重要了。我们从比较流行的一些风格中选择了一种,读者可以选择适合自己的一种风格,并养成一直使用这种风格的好习惯。

在该程序中,绝大部分工作都是在循环体中完成的。循环体中的赋值语句:

printf(" %d\t%d\n", fahr, celsius);

用于打印两个整数 fahr 与 celsius 的值,并在两者之间留一个制表符的空间(\t)。

printf 函数的第一个参数中的各个%分别对应于第二个、第三个、……参数,它们在数目和类型上都必须匹配,否则将出现错误的结果。

顺便指出,printf 函数并不是 C 语言本身的一部分,C 语言本身并没有定义输入/输出功能。printf 仅仅是标准库函数中一个有用的函数而已,这些标准序函数在 C 语言程序中通常都可以使用。但是,ANSI 标准定义了 printf 函数的行为,因此,对每个符合该标准的编译器和库来说,该函数的属性都是相同的。

上述的温度转换程序存在两个问题。比较简单的问题是,由于输出的数不是右对齐的,所以输出的结果不是很美观。这个问题比较容易解决:如果在 printf 语句的第一个参数的%d 中指明打印宽度,则打印的数字会在打印区域内右对齐。例如,可以用语句

printf(" %3d %6d\n", fahr, celsius);

打印 fahr 与 celsius 的值,这样,fahr 的值占 3 个数字宽,celsius 的值占 6 个数字宽,输出的结果如下所示:

 0 -17
 20  -6
 40  4
 60  15
 80  26
100  37
...

另一个较为严重的问题是,由于我们使用的是整型算术运算,因此经计算得到的摄氏温度值不太精确,例如,与 0℉对应的精确的摄氏温度应该为-17.8℃,而不是-17℃。为了得到更精确的结果,应该用浮点算术运算代替上面的整型算术运算。这就需要对程序做适当修改。下面是该程序的又一种版本

#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;
 upper = 300;
 step = 20;
 /* lower limit of temperatuire scale */
 /* upper limit */
 /* 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;
 }
}

这个程序与前一个程序基本相同,不同的是,它把 fahr 与 celsius 声明为 float 类型,转换公式的表述方式也更自然一些。在前一个程序中,之所以不能使用 5 / 9 的形式,是因为按整型除法的计算规则,它们相除并舍位后得到的结果为 0。但是,常数中的小数点表明该常数是一个浮点数,因此,5.0 / 9.0 是两个浮点数相除,结果将不被舍位。

如果某个算术运算符的所有操作数均为整型,则执行整型运算。但是,如果某个算术运算符有一个浮点型操作数和一个整型操作数,则在开始运算之前整型操作数将会被转换为浮点型。例如,在表达式 fahr – 32 中,32 在运算过程中将被自动转换为浮点数再参与运算。不过,即使浮点常量取的是整型值,在书写时最好还是为它加上一个显式的小数点,这样可以强调其浮点性质,便于阅读。
在这里需要注意,赋值语句 fahr = lower; 与条件测试语句 while (fahr <= upper) 也都是按照这种方式执行的,即在运算之前先把 int 类型的操作数转换为 float 类型的操作数。

printf 中的转换说明%3.0f 表明待打印的浮点数(即 fahr)至少占 3 个字符宽,且不带小数点和小数部分;%6.1f 表明另一个待打印的数(celsius)至少占 6 个字符宽,且小数点后面有 1 位数字。其输出如下所示:

 0 -17.8
20  -6.7
40  4.4
...

格式说明可以省略宽度与精度,例如,%6f 表示待打印的浮点数至少有 6 个字符宽;%.2f指定待打印的浮点数的小数点后有两位小数,但宽度没有限制;%f 则仅仅要求按照浮点数打印该数。

  • %d, 按照十进制整型数打印
  • %6d, 按照十进制整型数打印,至少 6 个字符宽
  • %f, 按照浮点数打印
  • %6f, 按照浮点数打印,至少 6 个字符宽
  • %.2f, 按照浮点数打印,至少 6 个字符宽
  • %6.2f, 按照浮点数打印,至少 6 个字符宽,小数点后有两位小数

此外,printf 函数还支持下列格式说明:%o 表示八进制数;%x 表示十六进制数;%c表示字符;%s 表示字符串;%%表示百分号(%)本身。

时间: 2015-11-27

C语言 常量,变量及数据详细介绍

一.数据 图片文字等都是数据,在计算机中以0和1存储. (一)分类 数据分为静态数据和动态数据. ①. 静态数据:一些永久性的的数据,一般存储在硬盘中,只要硬盘没坏数据都是存在的.一般以文件的形式存储在硬盘上,电脑关机重启后依然存在. ②. 动态数据:程序运行过程中,动态产生的的临时数据,一般存储在内存中,内存的存储空间一般较小,计算机关闭后这些数据就会被清除.软件或者电脑关闭则这些临时数据会被清除. ③. 静态数据和动态数据可以转换. ④. 注意:为什么不把动态数据存放到硬盘?因为直接访问内存

C语言菜鸟基础教程之常量和变量

先动手编写程序: #include <stdio.h> int main() { int a = 1; printf("a = %d\n", a); a = 2; printf("a = %d\n", a); return 0; } 运行结果: a = 1 a = 2 程序分析: int a = 1; 定义了一个整型变量a,把1赋值给a.注意,C语言中的等号表示赋值,作用是把一个常量赋值给一个变量,这样变量就获得了一个临时的固定值. 为什么说是临时的呢?

C语言菜鸟基础教程之判断

(一) 先动手编写一个程序: #include <stdio.h> int main() { if(1) { printf("The condition is true!\n"); } return 0; } 运行结果: The condition is true! 再把1依次改为,2,5,100,-10,发现运行结果完全一样. 再改成if(0),此时发现没有运行结果,说明printf()语句没被执行. C语言把判断语句中的任何非0或非空的值当作真.所以if(1), if(

C语言菜鸟基础教程之数据类型

C语言的数据类型有整型.浮点型(就是小数).字符.字符串.数组.结构体等.刚开始学的时候,不要一下子学太多.先学最基本的整型.浮点型和字符. 对于学习程序来说,最重要的是动手操作. 先编写程序: #include <stdio.h> int main() { int a = 1; printf("a = %d\n", a); float b = 2.2; printf("b = %f\n", b); char c = 'A'; printf("

C语言菜鸟基础教程之条件判断

(一)if...else 先动手编写一个程序 #include <stdio.h> int main() { int x = -1; if(x > 0) { printf("x is a positive number!\n"); } else { printf("x is not a positive number!\n"); } return 0; } 运行结果: x is not a positive number! 程序分析: 定义一个整数

C语言菜鸟基础教程之自定义函数

先动手编写程序: #include <stdio.h> int add(int x, int y) { int z = x + y; return z; } int main() { int a = 1; int b = 2; int c = add(a, b); printf("c = %d\n", c); return 0; } 运行结果: c = 3 程序分析: (1) 函数定义的形式为: 类型 函数名称(类型 形式参数,--) { 函数体 } (2) 对应于咱们的程

C语言菜鸟基础教程之加法

先动手编写程序: #include <stdio.h> int main() { int a = 1; int b = 2; int c = a + b; printf("sum is %d\n", c); return 0; } 运行结果: sum is 3 程序分析: 先定义一个整型变量a,把1赋值给a. 再定义一个整型变量b,把2赋值给b. 最后定义一个整型变量c,它的值不是靠赋值得到的,而是把a和b相加之后的值赋值给它,即c的值为3.

C语言菜鸟基础教程之单精度浮点数与双精度浮点数

上节课 简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的单位是字节(Byte,简写为B). 再大一级的是千字节(kilo Bytes),用k来表示. 再大一级的单位是兆字节(Mega Bytes),用M来表示.一张照片的大小通常为1~3M. 再大一级的单位为G.一部高清电影的大小通常为1~2G. 再大一级的单位为T. 换算关系为: 1B = 8bit 1

WAP建站WML语言语法基础教程第1/6页

完成WAP服务器的建立和WAP浏览器的安装之后,我们接下来就可以使用WML语言来编写WAP网页或应用,并通过WAP服务器及浏览器进行调试.从本章开始我们将系统地学习WML语言,本章主要讲解WML语言的基础知识,下一章全面讲解WML的语法.标签和规则. 2.1 WML的简单例子及编辑.测试方法 无限标记语言WML(Wireless Markup Language)是一种基于扩展标记语言XML(Extension Markup Language)的语言,是XML的子集.它可以显示各种文字.图像等数据

C语言菜鸟基础教程之a++与++a

(一)a++ 在C语言或其它语言中,++符号表示"自加",就是变量在原来的基础上加1. 例1: a = 0; a++; 则此时a的值为1. 同样的道理,--表示"自减". 例2: a = 100; a--; 则此时a的值为99. 注意,程序语言里没有"自乘"和"自除"的概念. 验证程序: #include <stdio.h> int main() { int a = 0; // 给a赋值 a++; printf(&

易语言基础教程之定义及变量

任何编程语言都离不开对变量的定义及引用,易语言也是如此.由于变量是实现信息处理以及数据计算的核心,因此掌握变量的定义及引用将显得格外重要.下面就一起来学习一下易语言中变量的那些事儿. 方法/步骤 创建一个"Windows窗口程序",并绘制如图所示的人机交互界面. 选中"按钮"组件,从"文件夹 属性"面板中为其添加"单击"事件. 接着在打开的"程序集"窗口中,输入代码"长 = 到数值 (编辑框1.内