C语言学习笔记(三)

学习C语言第三天

1.3 for语句
对于特定任务我们可以采用多种方法来编写程序。下面用for循环实现温度转换程序的功能。

#include <stdio.h>

/* 打印华氏温度-摄氏温度对照表 */
main() {
    int fahr;
    for (fahr = 0; fahr <= 300; fahr = fahr + 20)
        printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr -32));
}

while循环和for循环执行结果相同,但程序本身有所不同。做主要的改进是去掉了大部分变量,而值使用了一个int类型的变量fahr。温度的下限、上限和步长都是常量,而计算摄氏温度的表达式现在变成了printf函数的第三个参数,不再是一个单独的赋值语句。

C语言中一个通用规则:在允许使用某种类型变量值的任何场合,都可以使用该类型的更复杂的表达式。

for语句是对while语句的推广,更直观一些。圆括号中包含3个部分,各部分之间用分号隔开。第一部分

fahr = 0

是初始化部分,仅在进入循环前执行一次。第二部分

fahr <= 300

是控制循环的测试或条件部分。循环控制将对条件求值,如果结果为真,则执行循环体。此后将执行第三个部分

fahr = fahr + 20

以将循环变量fahr增加一个步长,并再次对条件求值。如果计算得到的条件值为假,循环将终止执行。3部分内容都可以是任何表达式。

练习1-5 修改温度转换程序,要求以逆序(即按照从300度到0度的顺序)打印温度转换表。

#include <stdio.h>

/* 逆序打印华氏温度-摄氏温度表 */
main() {
    int fahr;
    
    for(fahr = 300; fahr >= 0; fahr = fahr - 20)
        printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr -32));
}

______________________________________________________________________________

1.4 符号常量
在程序中使用300、20等类似的“幻数”并不是一个好习惯,他们几乎无法想以后阅读改程序的人提供什么信息,而且使程序的修改变得更加困难。处理这种幻数的一种方法是赋予它们有意义的名字。#define指令可以把符号名(或称为符号常量)定义为一个特定的字符串:

#define 名字    替换文本

在该定义后,程序中出现的所有在#define中定义的名字(既没有用引号引起来,也不是其它名字的一部分)都将用相应的替换文本替换。替换文本可以是任何字符序列,而不仅限于数字。

#include <stdio.h>

#define     LOWER   0           /* 表的下限 */
#define     UPPER   300        /* 表的上限 */
#define     STEP      20         /*  步长*/

/* 打印华氏温度-摄氏温度对照表 */
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指令行的末尾没有分号。

1.5 字符输入/输出
接下来看一组与字符型数据处理有关的程序。许多程序只不过是这里讨论的程序原型的扩充版本而已。
标准库提供的输入/输出模型非常简单。无论文本从何处输入,输出到何处,其输入/输出都是按照字符流的方式处理。文本流是有多行字符构成的字符序列,而每行字符则由0个或者多个字符组成,行末是一个换行符。标准库负责使每个输入/输出六都能遵守这一模型。使用标准库的C语言程序员不必关心程序外这些行是如何表示的。
标准库提供了一次读/写一个字符的函数,其中最简单的是getchar和putchar两个函数。每次调用是,getchar函数从文本流中读入下一个输入字符,并将其作为结果值返回。也就是说,在执行语句

c = getchar()

之后,变量c中将包含输入流中的下一个字符。这种字符通常是通过键盘输入的。每次调用putchar函数时将打印一个字符。例如:

putchar(c)

将把整型变量c的内容以字符的形式打印出来,通常是显示在屏幕上。

1.5.1 文件复制

借助于getchar和putchar函数,可以在不了解其他输入/输出知识的情况下编写出数量惊人的有用代码。最简单的例子就是把输入 一次一个字符地复制到输出,其基本思想如下:

读一个字符
while(该字符不是文件结束符)
    输出刚读入的字符
    读入下一个字符

将上述基本思想转换为C语言程序为:

#include <stdio.h>

/* 将输入复制到输出:版本1*/
main() {
    int c;

    c = getchar();
    while (c != EOF)
    {
        putchar(c);
        c = getchar();
    }    
}

其中,关系运算符!=表示“不等于”。
字符在键盘、屏幕或其他任何地方无论以什么形式表现,它在机器内部都是以位模式存储的。char类型专门用于存储这种字符型数据,当然任何整型(int)也可以用于存储字符型数据。
这里需要解决如何区分文件中有效数据与输入结束符的问题。C语言采取的解决方法是:在没有输入时,getchar函数将返回一个特殊值,这个特殊值与任何实际字符都不同。这个值称为EOF(end of file,文件结束)。这里之所以不把c声明成char类型,是因为它必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF。
EOF定义在文件<stdio.h>中,是一个整型数。其具体数值是什么并不重要,只要它与任何char类型的值都不相同即可。

在C语言中,类似于

c = getchar()

之类的赋值操作是一个表达式,并且具有一个值,即赋值后左边变量保存的值。也就是说,赋值可以作为更大的表达式的一部分出现。改写程序如下:

#include <stdio.h>
/* 将输入复制到输出:版本2*/
main() {
    int c;

    while ((c = getchar()) != EOF)
        putchar(c);
}

以上这段程序将输入集中化,getchar函数在程序中只出现了一次,这样就缩短了程序,整个程序看起来更紧凑。习惯这种风格后,读之就会发现按照这种方式编写的程序更易阅读。我们经常会看到这种风格。(不过,如果过多的使用这种类型的复杂语句,编写的程序可能会难以理解,应该尽量避免这种情况)。
不等于运算符!=的优先级必赋值运算符=的优先级高,这样在不使用圆括号的情况下关系测试!=将在赋值=操作之前执行。因此语句

c = getchar() != EOF

等价于语句

c = (getchar() != EOF)

该语句执行后,c的值将被置为0或1,这并不是我们希望的结果。

练习1-6 验证表达式getchar() != EOF 的值是0还是1.
练习1-7 编写一个打印EOF值的程序。

#include <stdio.h>

main() {
    printf("练习1-6\n");
    printf("%d\n", (getchar() != EOF));  // 正常情况下是1
    printf("练习1-7\n");
    printf("%d\n", EOF);  // -1
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值