EOF 定义在头文件<stdio.h>中,是个整型数,其具体数值是什么并不重要,只要它与任何 char 类型的值都不相同即可。这里使用符号常量,可以确保程序不需要依赖于其对应的任何特定的数值。
对于经验比较丰富的 C 语言程序员,可以把这个字符复制程序编写得更精炼一些。在 C 语言中,类似于
c = getchar()
之类的赋值操作是一个表达式,并且具有一个值,即赋值后左边变量保存的值。也就是说,赋值可以作为更大的表达式的一部分出现。如果将为 c 赋值的操作放在 while 循环语句的测试部分中,上述字符复制程序便可以改写成下列形式:
#include <stdio.h>
/* copy input to output; 2nd version
*/
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
在该程序中,while 循环语句首先读一个字符并将其赋值给 c,然后测试该字符是否为文件结束标志。如果该字符不是文件结束标志,则执行 while 语句体,并打印该字符。随后重复执行 while 语句。当到达输入的结尾位置时,while 循环语句终止执行,从而整个 main 函数执行结束。
以上这段程序将输入集中化,getchar 函数在程序中只出现了一次,这样就缩短了程序,整个程序看起来更紧凑。习惯这种风格后,读者就会发现按照这种方式编写的程序更易阅读。我们经常会看到这种风格。(不过,如果我们过多地使用这种类型的复杂语句,编写的程序可能会很难理解,应尽量避免这种情况。)
对 while 语句的条件部分来说,赋值表达式两边的圆括号不能省略。不等于运算符!=的优先级比赋值运算符=的优先级要高,这样,在不使用圆括号的情况下关系测试!=将在赋值=操作之前执行。因此语句
c = getchar() != EOF
等价于语句
c = (getchar() != EOF)
该语句执行后,c 的值将被置为 0 或 1(取决于调用 getchar 函数时是否碰到文件结束标志),这并不是我们所希望的结果。
计算字符个数
下列程序用于对字符进行计数:
#include <stdio.h>
/* 统计输入的字符数 Version 1.0 */
main()
{
long nc;
nc = 0;
while(getchar() != EOF)
++nc;
printf("%ldn", nc);
}
其中,语句 ++nc; 引入了一个新的运算符++,其功能是执行加 1 操作。可以用语句 nc = nc + 1 代替它,但语句++nc 更精炼一些,且通常效率也更高。与该运算符相应的是自减运算符--。++与--这两个运算符既可以作为前缀运算符(如++nc),也可以作为后缀运算符(如 nc++)。我们在后面将看到,这两种形式在表达式中具有不同的值,但++nc 与 nc++都使 nc 的值增加 1。目前,我们只使用前缀形式。










