4.1. 函数的基本知识

image.png

最简单的函数:

  1. dummy() {}

如果没定义返回值, 默认为 int

4.2 返回非整型值的函数

double atof(char s[]) {

}

4.3 外部变量

函数之外.

  • 函数中不允许定义函数

image.png
image.png

image.png
image.png

image.png

精炼.

image.png

回退字符时利用缓冲区:

image.png

4.4 作用域规则

函数与外部变量可以分开编译.

在使用前就要定义好:

image.png

image.png

4.5 头文件

image.png

4.6 静态变量

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

image.png

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, 自动变量和寄存器变量的初值则没有定义
  • 初始化外部变量与静态变量的表达式必须是常量表达式

image.png

image.png

4.10 递归

image.png
image.png

image.png

快排的核心思想就是将数组划分成两个子集, 左边都小于哨兵, 右边都大于哨兵, 递归的是不断将子集继续划分.

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

image.png

其他指令:

#ifdef
#ifndef