4.1. 函数的基本知识

最简单的函数:
dummy() {}
如果没定义返回值, 默认为 int
4.2 返回非整型值的函数
double atof(char s[]) {
}
4.3 外部变量
函数之外.
- 函数中不允许定义函数





精炼.

回退字符时利用缓冲区:

4.4 作用域规则
函数与外部变量可以分开编译.
在使用前就要定义好:


4.5 头文件

4.6 静态变量
static 限定外部变量或函数的作用域为其所在源文件.

static 限定局部变量时, 其不会随函数退出而消失.
类似面向对象语言中的对象字段, 其方法使用该字段. static 貌似赋予了函数状态.
4.7 寄存器变量
register 声明告诉编译器, 它所声明的变量放在机器的寄存器中, 但编译器可忽略该声明.
register int x;
register char c;
// 只适用于自动变量和函数参数
f(register unsigned m, register long n) {
register int i;
}
不能访问寄存器变量的地址.
4.8 程序块结构
4.9 初始化
- 在不进行现实初始化的情况下, 外部变量和静态变量都将被初始化为0, 自动变量和寄存器变量的初值则没有定义
- 初始化外部变量与静态变量的表达式必须是常量表达式


4.10 递归



快排的核心思想就是将数组划分成两个子集, 左边都小于哨兵, 右边都大于哨兵, 递归的是不断将子集继续划分.
4.11 C 预处理器
#include
#define
4.11.1 文件包含
两种形式:
#include "file" // 在当前位置查找
#include <file> // 按照某些规则查找
4.11.2 宏替换
#define 名字 替换文本
可以使用多行 \ :
#define abc def\
ghi
作用域从定义点到该源文件末尾.
宏定义可以引用宏定义.
替换文本可以是语句:
#define forever for (;;)
可以带参数:
#define max(A,B) ((A) > (B) ? (A) : (B))
x = max(p+1, r+s);
// 被替换为
x = ((p+q) > (r+s) ? (p+q) : (r+s));
注意使用宏定义带来的问题:
- 带有自增的宏定义
max(i++, j++) // 错 - 运算顺序
square(x) x * x // 错square(z+1)
取消宏定义:
#undef getchar
int getchar(void) { ... }
使用字符串替换 #:
#define dprint(expr) printf(#expr " = %g\n", expr)
dprint(x/y);
// 替换为
printf("x/y" " = %g\n", x/y);
// 由于字符串连接, 等价于
printf("x/y = %g\n", x/y);
预处理器运算符 ##
#define paste(front, back) front ## back
paste(name, 1)
// 替换为
name1
4.11.3 条件包含
避免多次包含头文件:
#if !defined(HDR)
#define HDR
// hdr.h 文件的内容放在这里
#endif

其他指令:
#ifdef
#ifndef
