Note
本篇是《C Primer Plus》附录 B(Reference Section)的中文速查版。原书按主题分成九节:附加阅读、C 运算符、基本类型与存储类别、表达式与语句与程序流、标准 ANSI C 库(含 C99 增补)、扩展整数类型、扩展字符支持、C99 数值计算增强、C 与 C++ 的差异。这里把它重排为便于随手翻查的表格——写代码卡壳时,先来这一篇找答案,再去原书对应章节看细节。
18.1 运算符优先级全表
按优先级从高到低排列(同格内按结合性从左到右或从右到左结合)。除注明外均为二元运算符;注意 *(乘法)与 *(解引用)、-(减法)与 -(负号)同符号但优先级不同。
| 优先级 | 运算符 | 结合性 | 说明 |
|---|---|---|---|
| 1(最高) | ++ --(后缀)、()(函数调用)、[]、{}(复合字面量)、.、-> | 从左到右 | 后缀自增/自减、下标、成员访问 |
| 2 | ++ --(前缀)、- +(一元)、~ !、sizeof、*(解引用)、&(取地址)、(type)(强制转换),均为一元 | 从右到左 | 单目运算符一族 |
| 3 | (类型名) | 从右到左 | 强制类型转换 |
| 4 | * / % | 从左到右 | 乘除取模(% 仅限整数) |
| 5 | + -(二元) | 从左到右 | 加减 |
| 6 | << >> | 从左到右 | 左移、右移 |
| 7 | < > <= >= | 从左到右 | 关系比较 |
| 8 | == != | 从左到右 | 相等比较(注意别写成 =) |
| 9 | & | 从左到右 | 按位与 |
| 10 | ^ | 从左到右 | 按位异或 |
| 11 | | | 从左到右 | 按位或 |
| 12 | && | 从左到右 | 逻辑与(短路求值) |
| 13 | || | 从左到右 | 逻辑或(短路求值) |
| 14 | ? :(条件表达式) | 从右到左 | 唯一的三目运算符 |
| 15 | = *= /= %= += -= <<= >>= &= |= ^= | 从右到左 | 赋值与复合赋值 |
| 16(最低) | ,(逗号运算符) | 从左到右 | 先求左表达式,整体取右表达式的值 |
记忆抓手:后缀 > 一元 > 乘除 > 加减 > 移位 > 关系 > 相等 > 位运算(与、异或、或)> 逻辑与 > 逻辑或 > 条件 > 赋值 > 逗号。

18.2 关键字速查
C 的基本数据类型由 8 个关键字组合而成:int、long、short、unsigned、char、float、double、signed(ANSI C);C99 又新增 _Bool、_Complex、_Imaginary、long long、restrict 等。
| 类别 | 类型/关键字 | 要点 |
|---|---|---|
| 有符号整数 | int | 系统的基本整数类型,宽度依实现而定 |
long / long int | 至少 32 位,不小于 int | |
short / short int | 至少 16 位,不大于 int | |
long long(C99) | 至少 64 位,不小于 long | |
| 无符号整数 | unsigned int/long/short/long long | 只表示 0 和正数,扩大正数范围;单独的 unsigned 等价 unsigned int |
| 字符 | char | 按定义占 1 字节;signed char 与 unsigned char 是两个独立类型 |
| 布尔 | _Bool(C99) | 只取 0/1;含 stdbool.h 后可用 bool、true、false |
| 实浮点 | float | 至少 6 位有效数字,通常 32 位 |
double | 至少 10 位有效数字,通常 64 位 | |
long double | 可能比 double 更大更精 | |
| 复数/虚数(C99) | float/_Complex 等 | 内部按两个实数元素的数组存储(实部、虚部);虚数类型可选 |
存储类别(storage class)决定变量的作用域、链接与存储期:
| 存储类别 | 存储期 | 作用域 | 链接 | 声明方式 |
|---|---|---|---|---|
| 自动(auto) | 自动 | 块 | 无 | 块内(默认) |
| 寄存器(register) | 自动 | 块 | 无 | 块内加 register |
| 静态外部链接 | 静态 | 文件 | 外部 | 所有函数之外(默认) |
| 静态内部链接 | 静态 | 文件 | 内部 | 所有函数之外加 static |
| 静态无链接 | 静态 | 块 | 无 | 块内加 static |
类型限定符(qualifier):
| 限定符 | 含义 |
|---|---|
const | 初始化后不可修改。const int * p:p 指向的数据不可改;int * const p:p 本身不可改 |
volatile | 提醒编译器该变量可能被程序之外的因素(如硬件)改变,禁止过度优化 |
restrict(C99) | 承诺该指针是相应内存块的唯一访问途径(如函数原型 void interleave(int * restrict p1, int * restrict p2, int n) 隐含两块内存不重叠) |
18.3 语句与程序流速查
| 语句 | 类别 | 形式 | 要点 |
|---|---|---|---|
while | 入口条件循环 | while (表达式) 语句 | 先判断后执行,循环体可能一次都不跑 |
for | 入口条件循环 | for (初始化; 测试; 更新) 语句 | 三个控制表达式用分号隔开;C99 允许初始化部分声明变量(作用域限于循环) |
do while | 出口条件循环 | do 语句 while (表达式); | 先执行后判断,循环体至少执行一次 |
if / if else | 分支 | if (表达式) 语句 else 语句 | 表达式非零即为”真”,可级联 else if |
switch | 多重分支 | switch (表达式) { case 常量: ... default: ... } | 表达式与标签必须是整数值;匹配后一直执行到 break 或结尾(穿透) |
break | 跳转 | break; | 终止所在循环或 switch;不能用于循环外的 if |
continue | 跳转 | continue; | 跳过本轮剩余语句;while/for 直接进入测试,do while 先测退出条件 |
goto | 跳转 | goto 标签; / 标签: 语句 | 可前跳可后跳;现代代码尽量少用 |
| 复合语句 | — | { 语句... } | 花括号包裹的块,等效于一条语句 |
18.4 标准库头文件总览
ANSI C 库按功能分组,每组对应一个头文件。下表为”按需取用”的导航图:
| 头文件 | 主题 | 代表内容 |
|---|---|---|
assert.h | 诊断 | assert() 宏:表达式为假时打印诊断信息并调用 abort();定义 NDEBUG 可关闭 |
ctype.h | 字符处理 | isalpha()、isdigit()、isspace()、toupper()、tolower() 等 |
errno.h | 错误报告 | errno 及宏 EDOM(定义域错误)、ERANGE(值域错误)、EILSEQ(宽字符转换错误) |
float.h | 浮点特性 | FLT_RADIX、FLT_MAX、DBL_DIG 等实现常量 |
limits.h | 整型限制 | INT_MAX、CHAR_BIT、LONG_MIN 等 |
locale.h | 本地化 | setlocale()、localeconv()、LC_ALL 等类别宏 |
math.h | 数学库 | sin()、sqrt()、pow()、ceil()、fabs() 及 C99 新函数(见 18.6) |
setjmp.h | 非本地跳转 | setjmp() 保存执行环境,longjmp() 跳回;用于错误处理 |
signal.h | 信号处理 | signal() 设置信号响应,raise() 发送信号;宏 SIGINT、SIGABRT 等 |
stdarg.h | 可变参数 | va_list 类型与 va_start()、va_arg()、va_end()、va_copy() 宏 |
stdbool.h(C99) | 布尔支持 | bool→_Bool、true→1、false→0 |
stddef.h | 常用定义 | size_t、ptrdiff_t、wchar_t 类型与 NULL、offsetof() 宏 |
stdint.h(C99) | 扩展整数 | int32_t、uint_least16_t 等定宽类型(见 18.7) |
inttypes.h(C99) | 扩展整数 I/O | 包含 stdint.h,提供 PRId32、SCNd32 等格式宏 |
stdio.h | 标准 I/O | printf()、scanf()、fopen()、fgets() 等全套输入输出 |
stdlib.h | 通用工具 | 内存管理、随机数、字符串转换、排序查找、exit() 等 |
string.h | 字符串处理 | strlen()、strcpy()、strcmp()、strcat()、strchr() 及内存函数 |
time.h | 日期时间 | clock()、time()、strftime()、struct tm |
complex.h(C99) | 复数 | complex 宏、虚数单位 I、csin()、creal()、cimag() 等 |
fenv.h(C99) | 浮点环境 | 状态标志与控制模式:fesetround()、feclearexcept() 等 |
iso646.h(C99) | 运算符别名 | and→&&、or→||、not→! 等 |
tgmath.h(C99) | 通用数学宏 | 按实参类型自动展开成 sin/sinf/sinl/csin 等对应函数 |
wchar.h(C99) | 宽字符工具 | wprintf()、wcscpy() 等宽字符版 I/O 与字符串函数 |
wctype.h(C99) | 宽字符分类 | iswdigit()、towlower() 等宽字符版字符函数 |
18.5 常用库函数速查(按头文件分组)
ctype.h —— 字符判断与转换
| 函数 | 返回真的条件(“真”即非零) |
|---|---|
isalnum(c) | 字母或数字 |
isalpha(c) | 字母 |
isblank(c) | 空格或水平制表符(C99) |
iscntrl(c) | 控制字符(如 Ctrl+B) |
isdigit(c) | 数字 |
isgraph(c) | 除空格外的可打印字符 |
islower(c) / isupper(c) | 小写 / 大写字母 |
isprint(c) | 可打印字符 |
ispunct(c) | 标点(可打印但非字母数字空格) |
isspace(c) | 空白字符:空格、换行、换页、回车、垂直/水平制表符 |
isxdigit(c) | 十六进制数字 |
tolower(c) / toupper(c) | 返回小写 / 大写形式;其余情况原样返回 |
stdio.h —— 标准 I/O 高频函数
| 函数 | 功能 |
|---|---|
printf() / scanf() | 标准输出 / 输入的格式化 I/O |
fprintf() / fscanf() | 对指定流的格式化 I/O |
sprintf() / sscanf() / snprintf() | 以字符串为对象的格式化 I/O(snprintf 限长,更安全) |
getchar() / putchar() | 标准输入 / 输出单个字符 |
gets() / puts() | 整行读取(无长度限制,危险)/ 输出字符串 |
fgets() / fputs() | 对指定流的整行读写 |
fopen() / fclose() | 打开 / 关闭文件,返回 FILE * |
fgetc() / fputc() / getc() / putc() | 流上的单字符读写 |
fread() / fwrite() | 二进制块读写 |
fseek() / ftell() / rewind() | 移动 / 查询 / 归零文件位置指针 |
feof() / ferror() / clearerr() | 测试文件尾 / 错误 / 清除指示器 |
remove() / rename() / tmpfile() | 删除 / 重命名文件、创建临时文件 |
ungetc() | 把字符推回流上 |
stdlib.h —— 内存、随机数与转换
| 函数 | 功能 |
|---|---|
malloc(size) | 分配 size 字节(不初始化),成功返回地址,失败返回 NULL |
calloc(nmem, size) | 为 nmem 个元素分配空间并全部清零 |
realloc(ptr, size) | 调整已分配块的大小,内容保留到新旧尺寸中较小者 |
free(ptr) | 释放 malloc/calloc/realloc 分配的空间 |
rand() / srand(seed) | 伪随机数(0 到 RAND_MAX)/ 设置随机种子 |
atoi() / atol() / atof() | 字符串转 int / long / double(失败返回 0) |
strtol() / strtoul() / strtod() | 更健壮的字符串转换:可指定进制、报告转换终止位置 |
exit(status) / abort() | 正常退出(先执行 atexit 注册函数)/ 异常终止 |
atexit(func) | 注册程序正常结束时调用的函数(逆序执行) |
qsort(base, nmem, size, comp) | 任意类型数组的快速排序,比较函数由用户提供 |
bsearch(key, base, nmem, size, comp) | 有序数组的二分查找 |
system(str) / getenv(name) | 执行宿主命令 / 读取环境变量 |
string.h —— 字符串与内存
| 函数 | 功能 |
|---|---|
strlen(s) | 字符串长度(不含结尾空字符) |
strcpy(s1, s2) / strncpy(s1, s2, n) | 复制字符串 / 至多 n 个字符 |
strcat(s1, s2) / strncat(s1, s2, n) | 追加字符串 / 至多 n 个字符 |
strcmp(s1, s2) | 比较字符串:负 / 0 / 正表示小于 / 等于 / 大于 |
strncmp(s1, s2, n) | 只比较前 n 个字符 |
strchr(s, c) / strrchr(s, c) | 查找字符首次 / 最后一次出现的位置 |
strstr(s1, s2) | 查找子串 s2 在 s1 中首次出现的位置 |
strpbrk(s1, s2) | 查找 s2 中任一字符在 s1 中的首次出现 |
strspn() / strcspn() | 计算”全在 / 全不在 s2 字符集”的前缀长度 |
strtok(s, seps) | 按分隔符把字符串切成 token;后续调用首参传 NULL |
strerror(errnum) | 返回错误编号对应的消息字符串 |
memcpy() / memmove() | 复制 n 字节;后者允许内存重叠,更安全 |
memcmp() / memchr() / memset() | 比较 / 查找 / 填充 n 字节内存 |
math.h —— 数学函数(double 版)
| 函数 | 功能 |
|---|---|
sin() cos() tan() 及 asin() atan() atan2(y, x) | 三角与反三角(弧度制) |
sinh() cosh() tanh() | 双曲函数 |
exp() log() log10() | e^x、自然对数、常用对数 |
pow(x, y) sqrt() cbrt()(C99) | 乘方、平方根、立方根 |
fabs() ceil() floor() fmod(x, y) | 绝对值、向上 / 向下取整、x/y 余数 |
hypot(x, y)(C99) | √(x²+y²) |
round() trunc() rint()(C99) | 四舍五入(半值远离零)/ 截断 / 按当前舍入方向取整 |
fmax() fmin() fdim()(C99) | 最大值 / 最小值 / 正差 |
isnan() isfinite() isnormal()(C99 宏) | 数值分类:NaN、有限、正常 |
18.6 扩展整数类型(stdint.h / inttypes.h)
C99 用 typedef 提供按位宽命名的整数类型,配套 PRI…/SCN… 格式宏用于 printf()/scanf():
#include <inttypes.h>
int32_t cd_sales; /* 无论平台,恒为 32 位 */
scanf("%" SCNd32, &cd_sales);
printf("CD sales = %10" PRId32 " units\n", cd_sales);| 类型家族 | 形式 | 特点 |
|---|---|---|
| 精确宽度 | intN_t / uintN_t(N=8,16,32,64) | 恰好 N 位;个别系统可能不支持某宽度 |
| 最小宽度 | int_leastN_t / uint_leastN_t | 至少 N 位;一定存在 |
| 最快最小宽度 | int_fastN_t / uint_fastN_t | 至少 N 位且运算最快的一档 |
| 最大宽度 | intmax_t / uintmax_t | 系统中最宽的有符号 / 无符号整数 |
| 可存指针 | intptr_t / uintptr_t | 能无损容纳指针值的整数(可选) |

18.7 C 与 C++ 的主要差异一览
把 C 程序丢给 C++ 编译器时,以下几处最容易踩坑:
| 差异点 | C | C++ |
|---|---|---|
| 函数原型 | 可选;空括号表示”未声明参数” | 强制;空括号等于 (void) |
| char 常量 | 按 int 处理('ABCD' 可当 4 字节整数) | 按 char 处理 |
全局 const | 外部链接 | 内部链接(相当于 C 的 static const) |
| 结构标签作类型名 | 须写 struct duo m; | 可直接写 duo n; |
| 枚举赋值 | 整数赋给枚举变量仅告警 | 必须显式强转,season++ 也非法 |
void * 赋给其他指针 | 合法 | 必须显式强转 |
| 布尔类型 | _Bool(含 stdbool.h 后用 bool) | 内建 bool,true/false 是关键字 |
| 运算符别名 | 需 #include <iso646.h> | and、or 等是关键字 |
速查使用姿势
- 卡在优先级:回到 18.1 从下往上数层级,拿不准就加括号——括号永远免费。
- 忘记函数原型:先查 18.4 定位头文件,再到 18.5 对应分组找函数签名。
- 需要跨平台固定位宽:用 18.6 的
int32_t一族 + 格式宏,别再赌int的宽度。- const 与指针的先后顺序:读 18.2 限定符表那两行——
const在*左边锁数据,在*右边锁指针。- 本篇只收录高频内容;完整原型与罕见函数请查阅原书附录 B 或实现文档。