• C语言学习笔记(三)


    学习C语言第三天

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

    #include

    /* 打印华氏温度-摄氏温度对照表 */
    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

    /* 逆序打印华氏温度-摄氏温度表 */
    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

    #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

    /* 将输入复制到输出:版本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定义在文件中,是一个整型数。其具体数值是什么并不重要,只要它与任何char类型的值都不相同即可。

    在C语言中,类似于

    c = getchar()

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

    #include
    /* 将输入复制到输出:版本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

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

  • 相关阅读:
    CSS基础选择器总结
    二十四节气-白露 | 白露至,秋实美
    Javascript_Study
    Mac用NTFS文件夹读写NTFS硬盘 NTFS能复制多大的文件
    基于kubernetes CI/CD实践
    FastDFS安装笔记
    宏任务、微任务,怎么执行的
    艺术VQA的数据集与基线baselines
    设计模式使用场景实现示例及优缺点(结构型模式——代理模式、外观模式)
    Zookeeper(1)-安装与基础使用
  • 原文地址:https://blog.csdn.net/u014360189/article/details/127930776