《C Primer Plus 第六版》读书笔记 - 第七至九章
- C 控制语句:分支和跳转
- 字符输入/输出和输入验证
- 函数
第 7 章 C 控制语句:分支和跳转
7.2 if else 语句
7.2.2 ctype.h 系列的字符函数
C 有一系列专门] 处理字符的函数,ctype.h 头文件包含了这些函数的原型。这些函数接受一个字符作为参数,如果该字符属于某特殊的类别,就返回一个非零值(真):否则,返回 0(假)。例如,如果 isalpha() 函数的参数是一个字母,则返回一个非零值
7.2.3 多重选择 else if
整个 if else 语句被视为一条语句因此不必把嵌套的 if else 语句用花括号括起来。
7.2.4 else 与 if 配对
如果没有花括号,else 与离它最近的 if 匹配,除非最近的 if 被花括号括起来
7.3 逻辑运算符
7.3.1 备选拼写:iso646.h 头文件
C99 标准新增了可代替逻辑运算符的拼写,它们被定义在 ios646.h 头文件中。如果在程序中包含该头文件,便可用 and 代替&&、or 代替||、not 代替!
7.3.3 求值顺序
C 保证逻辑表达式的求值顺序是从左往右。&&和||运算符都是序列点,所以程序在从一个运算对象执行到下一个运算对象之前,所有的副作用都会生效。而且,C 保证一旦发现某个元素让整个表达式无效,便立即停止求值。
7.7 多重选择:switch 和 break
7.7.1 switch 语句
break 语句在其中起什么作用?它让程序离开 switch 语句,跳至 switch 语句后面的下一条语句。如果没有 break 语句,就会从匹配标签开始执行到 switch 末尾
switch 在圆括号中的测试表达式的值应该是一个整数值(包括 char 类型)。case 标签必须是整数类型(包括 char 类型)的常量或整型常量表达式(即,表达式中只包含整型常量)。不能用变量作为 case 标签。
1 | switch(整型表达式) |
7.8 goto 语句
goto 语句有两部分:goto 和标签名。标签的命名遵循变量命名规则,如下所示: 1
goto part2;
1
part2: printf("Refined analysis:\n");
第 8 章 字符输入/输出和输入验证
8.2 缓冲区
大部分系统在用户按下 Enter 键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。用户输入的字符被收集并储存在一个被称为缓冲区 (buffer) 的临时存储区,按下 Enter 键后,程序才可使用用户输入的字符。
缓冲分为两类:完全缓冲 I/O 和行缓冲 I/O。完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。缓冲区的大小取决于系统,常见的大小是 512 字节和 4096 字节。行缓冲 I/O 指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下 Enter 键后才刷新缓冲区。
回显输入意味着用户输入的字符直接显示在屏幕上,无回显输入意味着击键后对应的字符不显示
8.3 结束键盘输入
8.3.1 文件、流和键盘输入
从较低层面上,C 可以使用主机操作系统的基本文件工具直接处理文件,这些直接调用操作系统的函数被称为底层 I/O (low-level I/O)
从较高层面上,C 还可以通过标准 I/O 包 (standard I/O package) 来处理文件。这涉及创建用于处理文件的标准模型和一套标准 I/O 函数。在这一层面上,具体的 C 实现负责处理不同系统的差异,以便用户使用统一的界面
从概念上看,C 程序处理的是流而不是直接处理文件。流 (stream) 是一个实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的输入,由属性更统一的流来表示。于是,打开文件的过程就是把流与文件相关联,而且读写都通过流来完成。
8.3.2 文件结尾
在大多数 UNIX 和 Linux 系统中,在一行开始处按下 Ctrl+D 会传输文件结尾信号。许多微型计算机系统都把一行开始处的 Ctrl+Z 识别为文件结尾信号,一些系统把任意位置的 Ctrl+Z 解释成文件结尾信号。
8.4 重定向和文件
程序可以通过两种方式使用文件。第 1 种方法是,显式使用特定的函数打开文件、关闭文件、读取文件、写入文件,诸如此类。我们在第 13 章中再详细介绍这种方法。第 2 种方法是,设计能与键盘和屏幕互动的程序,通过不同的渠道重定向输入至文件和从文件输出。换言之,把 stdin 流重新赋给文件。
8.3.1 UNIX、Linux 和 DOS 重定向
使用重定向运算符不能读取多个文件的输入,也不能把输出定向至多个文件。
通常,文件名和运算符之间的空格不是必须的,除非是偶尔在 UNIX shell,Linux shell 或 Windows 命令行提示模式中使用的有特殊含义的字符。
第 9 章 函数
9.1 复习函数
9.1.2 分析程序
一般而言,函数原型指明了函数的返回值类型和函数接受的参数类型。这些信息称为该函数的签名 (signature)。
9.1.4 定义带形式参数的函数
ANSI C 也接受 ANSI C 之前的形式,但是将其视为废弃不用的形式 1
2
3void show_n_char(ch, num)
char ch;
int num;
9.1.5 声明带形式参数函数的原型
当函数接受参数时,函数原型用逗号分隔的列表指明参数的数量和类型。根据个人喜好,你也可以省略变量名: 1
void show_n_char(char, int);
9.1.6 调用带实际参数的函数
简而言之,形式参数是被调函数 (called function) 中的变量,实际参数是主调函数 (calling function) 赋给被调函数的具体值。
9.1.9 函数类型
声明函数时必须声明函数的类型。
9.3 递归
9.3.5 递归的优缺点
main() 也可以被自己或其他函数递归调用一一尽管很少这样做。
9.2 ANSI C 函数原型
9.2.1 问题所在
主调函数把它的参数储存在被称为栈 (stack) 的临时存储区,被调函数从栈中读取这些参数。
9.2.2 ANSI 的解决方案
声明的函数参数名不必与函数定义的形式参数名一致。
9.4 编译多源代码文件的程序
假定 Linux 系统安装了 GNU C 编译器 GCC。假设 file1.c 和 file2.c 是两个内含 C 函数的文件,下面的命令将编译两个文件并生成名为 a.out 的可执行文件: 1
gcc file1.c file2.c
1
gcc file1.c file2.o
9.4.5 使用头文件
在 UNIX 和 DOS 环境中,#include "hotels.h"
指令中的双引号表明被包含的文件位于当前目录中(通常是包含源代码的目录)。
《C Primer Plus 第六版》读书笔记 - 第七至九章