速查表
函数速查表
printf格式控制符表
| 格式控制符 | 含义 | 适用数据类型 | 参数说明 | 示例 | 输出结果(示例) |
|---|---|---|---|---|---|
| 整型相关 | |||||
| %d | 有符号十进制整数 | int、short | 接收int/short类型变量,按十进制输出 | printf("%d", 123); |
123 |
| %i | 有符号十进制整数(与%d功能一致) | int、short | 同%d,兼容早期C标准 | printf("%i", -45); |
-45 |
| %u | 无符号十进制整数 | unsigned int | 接收unsigned int类型,仅输出非负数 | printf("%u", 123U); |
123 |
| %o | 无符号八进制整数(无前缀0) | unsigned int | 按八进制输出,不显示前缀0 | printf("%o", 10); |
12 |
| %x | 无符号十六进制整数(小写字母,无前缀0x) | unsigned int | 0-9用数字,10-15用a-f | printf("%x", 255); |
ff |
| %X | 无符号十六进制整数(大写字母,无前缀0X) | unsigned int | 0-9用数字,10-15用A-F | printf("%X", 255); |
FF |
| %#o | 无符号八进制整数(带前缀0) | unsigned int | 自动添加前缀0标识八进制 | printf("%#o", 10); |
012 |
| %#x | 无符号十六进制整数(带前缀0x) | unsigned int | 自动添加前缀0x标识十六进制 | printf("%#x", 255); |
0xff |
| 浮点型相关 | |||||
| %f | 单/双精度浮点数(小数形式) | float、double | 接收float/double,默认保留6位小数 | printf("%f", 3.14); |
3.140000 |
| %lf | 双精度浮点数(printf中与%f无区别) | double | 仅在scanf中区分float(%f)和double(%lf) | printf("%lf", 3.1415); |
3.141500 |
| %e | 浮点数(指数形式,小写e) | float、double | 按尾数e+指数格式,尾数默认6位小数 |
printf("%e", 300.0); |
3.000000e+02 |
| %E | 浮点数(指数形式,大写E) | float、double | 按尾数E+指数格式,尾数默认6位小数 |
printf("%E", 300.0); |
3.000000E+02 |
| %g | 自动选%f/%e(短格式,无意义0不显示) | float、double | 优先用%f,若数值过大/过小自动切换%e,删除末尾无意义0 | printf("%g", 3.000); |
3 |
| %G | 自动选%f/%E(短格式,无意义0不显示) | float、double | 同%g,指数部分用大写E | printf("%G", 0.000300); |
0.0003 |
| 字符/字符串相关 | |||||
| %c | 单个字符 | char | 接收char类型,输出对应ASCII字符 | printf("%c", 'A'); |
A |
| %s | 字符串 | char*(字符串指针) | 接收以\0结尾的字符数组/指针,输出到\0停止 |
printf("%s", "Hello"); |
Hello |
| 指针相关 | |||||
| %p | 指针地址(十六进制形式) | void* | 接收任意类型指针,输出其内存地址(依赖系统位数) | int a; printf("%p", &a); |
0x7ffd42a1b23c(64位系统) |
| 特殊符号 | |||||
| %% | 输出一个百分号% | 无 | 无参数,用于打印%本身(避免被解析为格式符) | printf("%%"); |
% |
** printf附加格式修饰符表**
| 修饰符 | 含义 | 参数说明 | 示例 | 输出结果(示例) |
|---|---|---|---|---|
| %md | 输出宽度为m,不足用空格填充(右对齐) | m为int型,指定输出总宽度 | printf("%5d", 10); |
10(共5位,前面补3个空格) |
| %-md | 输出宽度为m,不足用空格填充(左对齐) | m为int型,-表示左对齐 | printf("%-5d", 10); |
10 (共5位,后面补3个空格) |
| %0md | 输出宽度为m,不足用0填充(右对齐) | m为int型,0表示用0填充空位 | printf("%05d", 10); |
00010(共5位,前面补3个0) |
| %m.nf | 输出宽度为m,保留n位小数 | m:总宽度;n:小数位数 | printf("%8.2f", 3.14159); |
3.14(总8位,前面4个空格,保留2位小数) |
| %.nf | 仅保留n位小数(宽度不限) | n:小数位数 | printf("%.3f", 3.14); |
3.140(保留3位小数) |
| %.f | 宽度和小数位由参数指定 | 第一个对应宽度m,第二个对应小数位n | printf("%*.*f", 8, 2, 3.14); |
3.14(等价于%8.2f) |
运算符优先级与结合性表
| 优先级(1最高,16最低) | 运算符 | 含义 | 操作数数量 | 结合性 | 参数/表达式示例 | 说明 |
|---|---|---|---|---|---|---|
| 1 | () | 函数调用/表达式分组 | 1(函数调用)/2(分组) | 左到右 | func(3, 4)、(a+b)*c |
函数调用时括号内为参数列表;分组时改变运算顺序 |
| 1 | [] | 数组下标 | 2(数组名+下标) | 左到右 | arr[5] |
等价于*(arr+5),下标为int型 |
| 1 | -> | 指针访问结构体成员 | 2(指针+成员名) | 左到右 | p->name |
p为结构体指针,name为结构体成员 |
| 1 | . | 结构体/联合体访问成员 | 2(变量+成员名) | 左到右 | obj.age |
obj为结构体变量,age为成员 |
| 2 | ++(后置) | 后置自增 | 1(变量) | 左到右 | a++ |
先使用a的值,再a=a+1 |
| 2 | --(后置) | 后置自减 | 1(变量) | 左到右 | a-- |
先使用a的值,再a=a-1 |
| 2 | & | 取地址 | 1(变量) | 右到左 | &a |
返回变量a的内存地址(指针类型) |
| 2 | * | 解引用(指针取值) | 1(指针) | 右到左 | *p |
返回指针p指向的变量值 |
| 2 | sizeof | 计算内存大小 | 1(类型/变量) | 右到左 | sizeof(int)、sizeof(a) |
返回字节数,类型需加括号,变量可省略 |
| 3 | ++(前置) | 前置自增 | 1(变量) | 右到左 | ++a |
先a=a+1,再使用a的值 |
| 3 | --(前置) | 前置自减 | 1(变量) | 右到左 | --a |
先a=a-1,再使用a的值 |
| 3 | +(正) | 正号 | 1(数值/变量) | 右到左 | +3、+a |
无实际运算,仅标识正数 |
| 3 | -(负) | 负号 | 1(数值/变量) | 右到左 | -3、-a |
取变量的相反数 |
| 3 | ! | 逻辑非 | 1(布尔值/变量) | 右到左 | !flag |
真(非0)变假(0),假变真(1) |
| 3 | ~ | 位非(按位取反) | 1(整型变量) | 右到左 | ~a |
对变量的每一位二进制取反(0变1,1变0) |
| 3 | (type) | 强制类型转换 | 1(变量/表达式) | 右到左 | (int)3.14 |
将数据转换为指定类型,可能丢失精度 |
| 4 | *(乘) | 乘法 | 2(数值/变量) | 左到右 | a*b |
整型/浮点型乘法 |
| 4 | /(除) | 除法 | 2(数值/变量) | 左到右 | a/b |
整型除法取商(如5/2=2),浮点除法取精确值(5.0/2=2.5) |
| 4 | %(取模) | 取余数 | 2(整型变量) | 左到右 | a%b |
仅支持整型,结果符号与被除数一致(如5%2=1,-5%2=-1) |
| 5 | +(加) | 加法 | 2(数值/变量) | 左到右 | a+b |
整型/浮点型加法 |
| 5 | -(减) | 减法 | 2(数值/变量) | 左到右 | a-b |
整型/浮点型减法 |
| 6 | <<(左移) | 按位左移 | 2(整型变量+移位位数) | 左到右 | a<<2 |
变量a的二进制左移2位,右边补0(等价于a*2^2) |
| 6 | >>(右移) | 按位右移 | 2(整型变量+移位位数) | 左到右 | a>>2 |
有符号数左补符号位,无符号数左补0(等价于a/2^2) |
| 7 | > | 大于 | 2(数值/变量) | 左到右 | a>b |
成立返回1(真),不成立返回0(假) |
| 7 | >= | 大于等于 | 2(数值/变量) | 左到右 | a>=b |
成立返回1,不成立返回0 |
| 7 | < | 小于 | 2(数值/变量) | 左到右 | a<b |
成立返回1,不成立返回0 |
| 7 | <= | 小于等于 | 2(数值/变量) | 左到右 | a<=b |
成立返回1,不成立返回0 |
| 8 | == | 等于 | 2(数值/变量/指针) | 左到右 | a==b、p==NULL |
比较值是否相等,成立返回1,不成立返回0 |
| 8 | != | 不等于 | 2(数值/变量/指针) | 左到右 | a!=b |
比较值是否不相等,成立返回1,不成立返回0 |
| 9 | &(位与) | 按位与 | 2(整型变量) | 左到右 | a&b |
对应位均为1则为1,否则为0 |
| 10 | ^(位异或) | 按位异或 | 2(整型变量) | 左到右 | a^b |
对应位不同则为1,相同则为0 |
| 11 | |(位或) | 按位或 | 2(整型变量) | 左到右 | a|b |
对应位有1则为1,否则为0 |
| 12 | &&(逻辑与) | 逻辑与 | 2(布尔值/表达式) | 左到右 | a&&b |
短路特性:左为假则右不执行,均为真返回1,否则0 |
| 13 | ||(逻辑或) | 逻辑或 | 2(布尔值/表达式) | 左到右 | a||b |
短路特性:左为真则右不执行,有一个真返回1,否则0 |
| 14 | ?:(条件运算符) | 三目运算 | 3(表达式1?表达式2:表达式3) | 右到左 | a>b?a:b |
表达式1为真则取表达式2的值,否则取表达式3的值 |
| 15 | = | 赋值 | 2(变量=表达式) | 右到左 | a=3、a=b+c |
将右边表达式的值赋给左边变量 |
| 15 | += | 加赋值 | 2(变量+=表达式) | 右到左 | a+=2 |
等价于a=a+2 |
| 15 | -= | 减赋值 | 2(变量-=表达式) | 右到左 | a-=2 |
等价于a=a-2 |
| 15 | *= | 乘赋值 | 2(变量*=表达式) | 右到左 | a*=2 |
等价于a=a*2 |
| 15 | /= | 除赋值 | 2(变量/=表达式) | 右到左 | a/=2 |
等价于a=a/2 |
| 15 | %= | 模赋值 | 2(变量%=表达式) | 右到左 | a%=2 |
等价于a=a%2 |
| 15 | <<= | 左移赋值 | 2(变量<<=位数) | 右到左 | a<<=2 |
等价于a=a<<2 |
| 15 | >>= | 右移赋值 | 2(变量>>=位数) | 右到左 | a>>=2 |
等价于a=a>>2 |
| 15 | &= | 位与赋值 | 2(变量&=表达式) | 右到左 | a&=b |
等价于a=a&b |
| 15 | ^= | 位异或赋值 | 2(变量^=表达式) | 右到左 | a^=b |
等价于a=a^b |
| 15 | |= | 位或赋值 | 2(变量|=表达式) | 右到左 | a|=b |
等价于a=a|b |
| 16 | ,(逗号运算符) | 表达式分隔 | 多个(表达式1,表达式2,...) | 左到右 | a=3, b=4, a+b |
从左到右依次执行,最终取最后一个表达式的值(结果为7) |
字符串操作函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
char *strcpy(char *dest, const char *src) |
将源字符串(含终止符\0)复制到目标缓冲区,覆盖目标缓冲区原有内容 |
- dest:char*,目标缓冲区(可读写,需足够大)- src:const char*,源字符串(只读,以\0结尾) |
成功:返回dest(目标缓冲区首地址)失败:无(但可能因缓冲区溢出导致程序崩溃) |
<string.h> |
1. 不安全:不检查dest长度,若src过长会溢出2. 自动复制 src的\0到dest |
char *strncpy(char *dest, const char *src, size_t n) |
将源字符串的前n个字符复制到目标缓冲区,是strcpy的安全版本,限制复制长度 |
- dest:char*,目标缓冲区- src:const char*,源字符串- n:size_t,最大复制字节数 |
成功:返回dest失败:无(相对安全,溢出风险低) |
<string.h> |
1. 相对安全:最多复制n字节2. 若 src长度≤n,复制src和\0;若src长度>n,仅复制前n字节,不自动加\0(需手动补) |
char *strcat(char *dest, const char *src) |
将源字符串追加到目标字符串的末尾(从目标字符串的\0位置开始),自动复制\0 |
- dest:char*,目标字符串(可读写,以\0结尾,需足够大)- src:const char*,源字符串(只读,以\0结尾) |
成功:返回dest失败:无(可能溢出) |
<string.h> |
1. 不安全:不检查dest剩余空间,src过长会溢出2. 从 dest的\0位置开始拼接,自动复制src的\0 |
char *strncat(char *dest, const char *src, size_t n) |
将源字符串的前n个字符追加到目标字符串末尾,自动添加\0,是strcat的安全版本 |
- dest:char*,目标字符串- src:const char*,源字符串- n:size_t,最大拼接字节数 |
成功:返回dest失败:无 |
<string.h> |
1. 安全:最多拼接n字节,自动在末尾加\02. 拼接长度 = min( strlen(src),n) |
int strcmp(const char *s1, const char *s2) |
按ASCII值逐字符比较两个字符串,直到遇到不同字符或\0,判断字符串的字典序关系 |
- s1:const char*,第一个字符串- s2:const char*,第二个字符串 |
返回值: - <0:s1字典序小于s2- 0:s1与s2完全相同- >0:s1字典序大于s2 |
<string.h> |
1. 按ASCII值逐字符比较,直到\0或不同字符2. 区分大小写(如 'A'(65)< 'a'(97)) |
size_t strlen(const char *s) |
计算字符串的长度(字节数),从字符串起始位置到第一个\0为止,不包含\0 |
- s:const char*,字符串(以\0结尾) |
成功:返回字符串长度(字节数,不含\0)失败:无( s为NULL会段错误) |
<string.h> |
1. 时间复杂度O(n),需遍历到\02. 若字符串无 \0,会越界访问(结果不确定) |
char *strchr(const char *s, int c) |
从字符串起始位置往后查找指定字符(含\0),返回首次出现该字符的指针 |
- s:const char*,字符串- c:int,要查找的字符(ASCII值,低8位有效) |
成功:返回指向该字符第一次出现位置的指针 失败:返回 NULL |
<string.h> |
1. 从字符串开头往后查找,包括\0(如strchr(s, '\0')返回s+strlen(s))2. 找到后返回的指针可用于修改字符(若 s非const) |
char *strrchr(const char *s, int c) |
从字符串末尾位置往前查找指定字符(含\0),返回最后一次出现该字符的指针 |
- s:const char*,字符串- c:int,要查找的字符 |
成功:返回指向该字符最后一次出现位置的指针 失败:返回 NULL |
<string.h> |
1. 从字符串末尾往前查找(反向查找) 2. 其他特性同 strchr |
char *strstr(const char *haystack, const char *needle) |
在主字符串中查找子字符串首次出现的位置,返回子字符串的起始指针;子字符串为空时返回主字符串 | - haystack:const char*,主字符串(被查找的字符串)- needle:const char*,子字符串(要查找的字符串) |
成功:返回指向子字符串第一次出现位置的指针 失败:返回 NULL |
<string.h> |
1. 若needle为空字符串,返回haystack(标准规定)2. 区分大小写,不支持通配符 |
char *strtok(char *str, const char *delim) |
按指定分隔符集合分割字符串,将分隔符替换为\0,返回当前分割的子字符串指针 |
- str:char*,要分割的字符串(首次调用传非NULL,后续传NULL)- delim:const char*,分隔符集合(如",. "表示逗号、句号、空格均为分隔符) |
成功:返回当前分割出的子字符串指针 失败/分割完毕:返回 NULL |
<string.h> |
1. 修改原字符串:将分隔符替换为\02. 非线程安全(同一进程多个线程调用会相互干扰) 3. 示例: char s[]="a,b.c"; strtok(s, ",.");返回"a",下次传NULL返回"b" |
void *memcpy(void *dest, const void *src, size_t n) |
按字节从源内存复制n字节数据到目标内存,不关心数据类型,支持任意内存块复制 |
- dest:void*,目标内存(可读写)- src:const void*,源内存(只读)- n:size_t,要复制的字节数 |
成功:返回dest失败:无( src/dest为NULL会段错误) |
<string.h> |
1. 按字节复制,不关心数据类型(可复制结构体、数组等) 2. 源/目标内存重叠时行为未定义(需用 memmove) |
void *memmove(void *dest, const void *src, size_t n) |
按字节从源内存复制n字节数据到目标内存,内部处理内存重叠问题,是memcpy的安全版本 |
- dest:void*,目标内存- src:const void*,源内存- n:size_t,复制字节数 |
成功:返回dest失败:无 |
<string.h> |
1. 功能同memcpy,但内部会处理内存重叠(先将数据临时存储)2. 比 memcpy稍慢,但更安全 |
void *memset(void *s, int c, size_t n) |
按字节将目标内存的前n字节设置为指定值c,常用于内存初始化(如清零) |
- s:void*,目标内存(可读写)- c:int,填充值(按字节填充,低8位有效)- n:size_t,填充字节数 |
成功:返回s失败:无 |
<string.h> |
1. 仅按字节填充,不适用于int数组初始化(如memset(arr, 1, sizeof(arr))会将每个字节设为1,int值为0x01010101≠1)2. 常用场景:内存清零( memset(s, 0, n)) |
标准IO函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
FILE *fopen(const char *pathname, const char *mode) |
打开指定文件,返回文件指针用于后续IO操作;文件不存在时根据mode决定是否创建 | - pathname:const char*,指定文件的完整路径(如"/home/test.txt")或当前目录文件名(如"test.txt")- mode:const char*,打开模式,常用值:- "r":只读,文件不存在则失败- "w":只写,文件不存在则创建,存在则清空内容- "a":追加写,文件不存在则创建,写入从文件尾开始- "r+":读写,文件不存在则失败- "w+":读写,文件不存在则创建,存在则清空- "a+":读写,文件不存在则创建,写入从文件尾开始 |
成功:返回指向FILE结构体的指针(文件指针),用于后续IO操作失败:返回 NULL,并设置errno(可通过perror打印错误) |
<stdio.h> |
1. 文本文件与二进制文件打开模式一致(Linux下无区别) 2. 打开后必须调用 fclose关闭,避免资源泄漏 |
int fclose(FILE *stream) |
关闭已打开的文件指针,释放文件相关资源,并自动刷新缓冲区数据到文件 | - stream:FILE*,fopen返回的文件指针 |
成功:返回0 失败:返回-1,并设置 errno |
<stdio.h> |
1. 关闭前会自动刷新缓冲区(全缓冲/行缓冲) 2. 关闭后 stream指针变为野指针,不可再使用 |
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) |
从指定文件中按数据块读取数据,存储到用户缓冲区,适用于二进制文件或批量数据读取 | - ptr:void*,用户缓冲区指针(用于存储读取到的数据,需提前分配内存)- size:size_t,单个数据块的字节数(如sizeof(int))- nmemb:size_t,要读取的数据块数量- stream:FILE*,文件指针 |
成功:返回实际读取的数据块数量(不是字节数) 失败/EOF:返回0,需通过 feof(stream)判断是否到文件尾,ferror(stream)判断是否错误 |
<stdio.h> |
1. 适用于二进制文件(如图片、视频),也可用于文本文件 2. 读取字节数 = 返回值 × size 3. 若读取到部分数据(如文件尾),返回值小于nmemb |
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) |
将用户缓冲区中的数据按数据块写入指定文件,适用于二进制文件或批量数据写入 | - ptr:const void*,用户缓冲区指针(存储要写入的数据)- size:size_t,单个数据块的字节数- nmemb:size_t,要写入的数据块数量- stream:FILE*,文件指针 |
成功:返回实际写入的数据块数量 失败:返回0,并设置 errno |
<stdio.h> |
1. 写入字节数 = 返回值 × size 2. 全缓冲模式下,数据先存缓冲区,满了才写入文件;需 fflush强制刷新 |
int fgetc(FILE *stream) |
从指定文件中读取单个字符,文件指针自动向后移动,支持文本文件的字符级读取 | - stream:FILE*,文件指针(如stdin表示标准输入) |
成功:返回读取到的字符(ASCII值,范围0-255) 失败/EOF:返回 EOF(宏定义为-1) |
<stdio.h> |
1. 每次读取1个字符,文件指针自动后移 2. 读取标准输入时, stream为stdin(如fgetc(stdin)等价于getchar()) |
int fputc(int c, FILE *stream) |
向指定文件中写入单个字符,文件指针自动向后移动,支持文本文件的字符级写入 | - c:int,要写入的字符(ASCII值,低8位有效)- stream:FILE*,文件指针(如stdout表示标准输出) |
成功:返回写入的字符(ASCII值) 失败:返回 EOF |
<stdio.h> |
1. 每次写入1个字符,文件指针自动后移 2. 写入标准输出时, stream为stdout(如fputc('A', stdout)等价于putchar('A')) |
char *fgets(char *s, int size, FILE *stream) |
从指定文件中按行读取文本数据,存储到用户字符数组,自动添加字符串终止符\0 |
- s:char*,用户字符数组(存储读取的行数据)- size:int,数组最大长度(需预留1字节存\0)- stream:FILE*,文件指针 |
成功:返回s(数组首地址)失败/EOF:返回 NULL |
<stdio.h> |
1. 读取到\n或size-1字节后停止,自动在末尾加\02. 会读取 \n并存入数组(区别于gets)3. 避免缓冲区溢出( size需小于数组长度) |
int fputs(const char *s, FILE *stream) |
将指定字符串写入目标文件,写入到字符串终止符\0为止,不自动添加换行符 |
- s:const char*,要写入的字符串(需以\0结尾)- stream:FILE*,文件指针 |
成功:返回非负整数(具体值依赖系统) 失败:返回 EOF |
<stdio.h> |
1. 不自动添加\n(区别于puts)2. 写入到 \0停止,\0不写入文件 |
int fprintf(FILE *stream, const char *format, ...) |
按指定格式将可变参数数据写入目标文件,支持格式化输出(如整数、字符串、浮点数) | - stream:FILE*,文件指针(如stdout表示屏幕输出)- format:const char*,格式控制字符串(含%d、%s等)- ...:可变参数,与format中的格式符一一对应 |
成功:返回实际写入的字节数(不含\0)失败:返回负数 |
<stdio.h> |
1. 格式符需与参数类型匹配(如%d对应int)2. 标准输出用 fprintf(stdout, ...),等价于printf(...) |
int fscanf(FILE *stream, const char *format, ...) |
按指定格式从目标文件中读取数据,存储到指定变量,支持格式化输入 | - stream:FILE*,文件指针(如stdin表示键盘输入)- format:const char*,格式控制字符串- ...:可变参数,需传变量地址(如&a) |
成功:返回成功匹配并赋值的参数个数 失败/EOF:返回 EOF |
<stdio.h> |
1. 跳过空白符(空格、\t、\n)2. 读取字符串时,遇空白符停止(不读取空白符) 3. 标准输入用 fscanf(stdin, ...),等价于scanf(...) |
int fseek(FILE *stream, long offset, int whence) |
调整文件指针的位置,实现文件的随机访问,支持从文件头、当前位置或文件尾偏移 | - stream:FILE*,文件指针- offset:long,偏移量(正数向右移,负数向左移)- whence:int,偏移基准:- SEEK_SET:从文件头开始(offset≥0)- SEEK_CUR:从当前位置开始- SEEK_END:从文件尾开始(offset常为负) |
成功:返回0 失败:返回-1,并设置 errno |
<stdio.h> |
1. 用于随机访问文件,不适用于管道、socket等流式文件 2. 文本文件中,offset需为 ftell返回值(避免换行符转换问题) |
long ftell(FILE *stream) |
获取当前文件指针相对于文件头的偏移量(字节数),用于记录文件位置或计算文件长度 | - stream:FILE*,文件指针 |
成功:返回当前位置到文件头的字节数 失败:返回-1L,并设置 errno |
<stdio.h> |
1. 常与fseek配合使用(如记录当前位置,后续恢复)2. 文本文件中,换行符可能被转换(如Windows下 \n存为\r\n),影响字节数计算 |
int fflush(FILE *stream) |
强制刷新文件的缓冲区,将缓冲区中的数据立即写入文件,避免数据滞留丢失 | - stream:FILE*,文件指针;若为NULL,刷新所有打开的流 |
成功:返回0 失败:返回 EOF,并设置errno |
<stdio.h> |
1. 强制将缓冲区数据写入文件(适用于全缓冲/行缓冲) 2. 标准输出 stdout默认行缓冲,加\n或fflush(stdout)可刷新3. 只读流(如 "r"模式)调用fflush行为未定义 |
系统IO函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
int open(const char *pathname, int flags, ...) |
打开或创建指定文件,返回文件描述符用于底层IO操作;支持细粒度的打开选项(如非阻塞、追加) | - pathname:const char*,文件路径/名称(同fopen)- flags:int,打开选项(必选+可选组合,用|连接):- 必选(三选一): O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)- 可选: O_CREAT(文件不存在则创建,需传第3参数mode)、O_APPEND(追加写,每次写前移到文件尾)、O_TRUNC(文件存在则清空)、O_NONBLOCK(非阻塞模式)- ...:可变参数,仅当flags含O_CREAT时有效,为mode_t mode(文件权限,如0644) |
成功:返回文件描述符(非负整数,0=标准输入,1=标准输出,2=标准错误) 失败:返回-1,并设置 errno |
<fcntl.h> |
1. 权限计算:实际权限 = mode - umask(系统默认umask为0022或0002) 2. 打开后需调用 close关闭,避免描述符泄漏3. 区别于 fopen:返回文件描述符(int),而非文件指针(FILE*) |
int close(int fd) |
关闭指定的文件描述符,释放文件相关内核资源;若多个描述符指向同一文件,需全部关闭才释放文件 | - fd:int,open返回的文件描述符 |
成功:返回0 失败:返回-1,并设置 errno |
<unistd.h> |
1. 关闭后fd不可再使用2. 若多个描述符指向同一文件(如 dup复制),需全部关闭才释放文件资源 |
ssize_t read(int fd, void *buf, size_t count) |
从指定文件描述符中读取数据,存储到用户缓冲区,支持底层字节级读取 | - fd:int,文件描述符- buf:void*,用户缓冲区(存储读取的数据,需提前分配)- count:size_t,要读取的最大字节数 |
成功:返回实际读取的字节数(0表示EOF) 失败:返回-1,并设置 errno |
<unistd.h> |
1. 阻塞模式下,若无数据则等待;非阻塞模式下,无数据返回-1(errno=EAGAIN)2. 读取字节数可能小于count(如文件尾、网络数据不完整) |
ssize_t write(int fd, const void *buf, size_t count) |
将用户缓冲区中的数据写入指定文件描述符,支持底层字节级写入 | - fd:int,文件描述符- buf:const void*,用户缓冲区(存储要写入的数据)- count:size_t,要写入的字节数 |
成功:返回实际写入的字节数 失败:返回-1,并设置 errno |
<unistd.h> |
1. 若磁盘满或缓冲区满,写入字节数可能小于count 2. 标准输出 fd=1,标准错误fd=2(如write(1, "Hello", 5)等价于printf("Hello")) |
off_t lseek(int fd, off_t offset, int whence) |
调整文件描述符对应的文件偏移量,实现底层文件的随机访问 | - fd:int,文件描述符- offset:off_t,偏移量(正数右移,负数左移)- whence:int,偏移基准(同fseek的SEEK_SET/SEEK_CUR/SEEK_END) |
成功:返回当前位置到文件头的字节数 失败:返回-1,并设置 errno |
<unistd.h> |
1. 适用于可随机访问的文件(如普通文件),不适用于管道、socket 2. 偏移到文件尾外会产生“文件空洞”(占用磁盘空间,但内容为0) |
int fcntl(int fd, int cmd, ...) |
对已打开的文件描述符进行控制操作,如获取/设置文件属性、复制描述符、设置非阻塞 | - fd:int,文件描述符- cmd:int,控制命令(常用):- F_GETFL:获取文件状态标志(如是否非阻塞)- F_SETFL:设置文件状态标志(如添加O_NONBLOCK)- F_DUPFD:复制文件描述符,返回最小未用描述符- ...:可变参数,依赖cmd(如F_SETFL需传标志值) |
成功:返回值依赖cmd(如F_GETFL返回标志值,F_DUPFD返回新描述符)失败:返回-1,并设置 errno |
<fcntl.h> |
1. 常用场景:设置非阻塞模式( fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) )2. 不同 cmd的参数和返回值需查阅man 2 fcntl |
int dup(int oldfd) |
复制指定的文件描述符,返回系统中最小的未使用文件描述符;新描述符与原描述符指向同一文件 | - oldfd:int,已打开的文件描述符 |
成功:返回最小未使用的新文件描述符 失败:返回-1,并设置 errno |
<unistd.h> |
1. 新描述符与oldfd指向同一文件,共享文件偏移量和状态2. 关闭其中一个描述符,不影响另一个 |
int dup2(int oldfd, int newfd) |
复制指定的文件描述符,并将新描述符指定为newfd;若newfd已打开,先关闭再复制 |
- oldfd:int,已打开的文件描述符- newfd:int,目标新描述符 |
成功:返回newfd失败:返回-1,并设置 errno |
<unistd.h> |
1. 若newfd已打开,先关闭newfd,再复制oldfd为newfd2. 常用于重定向(如 dup2(fd, 1)将标准输出重定向到fd对应的文件) |
内存操作函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
void *malloc(size_t size) |
从堆内存中申请指定字节数的连续内存块,不初始化内存内容(内容为随机值) | - size:size_t,要申请的堆内存字节数 |
成功:返回指向堆内存的指针(void*,需强制类型转换) 失败:返回 NULL,并设置errno |
<stdlib.h> |
1. 申请的内存未初始化(内容为随机值) 2. 需检查返回值是否为 NULL(避免野指针)3. 内存需用 free释放,否则内存泄漏 |
void *calloc(size_t nmemb, size_t size) |
从堆内存中申请nmemb × size字节的连续内存块,自动将内存初始化为0,适用于创建堆数组 |
- nmemb:size_t,元素个数- size:size_t,单个元素字节数 |
成功:返回指向堆数组的指针 失败:返回 NULL,并设置errno |
<stdlib.h> |
1. 申请nmemb × size字节的堆内存,并初始化为02. 等价于 malloc(nmemb×size) + memset(..., 0, ...)3. 适用于创建数组(如 calloc(5, sizeof(int))创建5个int的堆数组) |
void *realloc(void *ptr, size_t size) |
调整已有的堆内存块大小,可扩大或缩小;扩大时可能分配新内存并复制数据,缩小则截断内存 | - ptr:void*,已有的堆内存指针(malloc/calloc返回值;若为NULL,等价于malloc(size))- size:size_t,新的内存大小(字节数) |
成功:返回指向新堆内存的指针 失败:返回 NULL,原内存ptr不变 |
<stdlib.h> |
1. 若新size>原size:可能扩展原内存,或分配新内存并复制数据(原内存自动释放) 2. 若新size<原size:截断内存,多余部分释放 3. 避免用原指针接收返回值(失败时原指针被覆盖为 NULL) |
void free(void *ptr) |
释放之前通过malloc/calloc/realloc申请的堆内存,将内存归还给系统,避免内存泄漏 |
- ptr:void*,malloc/calloc/realloc返回的堆内存指针 |
无返回值 | <stdlib.h> |
1. 仅释放堆内存,不修改指针值(ptr变为野指针,需手动设为NULL)2. 不可重复释放(同一指针释放多次会崩溃) 3. 不可释放栈内存(如局部变量地址) |
void bzero(void *s, size_t n) |
将目标内存的前n字节清零,功能等价于memset(s, 0, n),是BSD扩展函数 |
- s:void*,目标内存(可读写)- n:size_t,要清零的字节数 |
无返回值 | <strings.h> |
1. 功能同memset(s, 0, n),仅清零2. 是BSD扩展函数,部分系统可能不支持(建议用 memset保证可移植性) |
进程操作函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
pid_t fork(void) |
创建子进程,子进程完全复刻父进程的内存空间(代码段、数据段、栈、堆),父子进程从fork后并发执行 |
无参数 | 成功: - 父进程:返回子进程的PID(正整数) - 子进程:返回0 失败:返回-1,并设置 errno |
<unistd.h> |
1. 子进程复刻父进程的内存空间(代码段、数据段、栈、堆),但PID不同 2. 父子进程并发执行,顺序不确定(需同步机制控制) 3. 子进程继承父进程的打开文件、环境变量等 |
pid_t wait(int *wstatus) |
阻塞等待任意子进程退出,回收子进程的内核资源,避免僵尸进程;可获取子进程退出状态 | - wstatus:int*,存储子进程退出状态;若为NULL,表示不关心退出状态 |
成功:返回回收的子进程PID 失败: - 无子进程:返回-1, errno=ECHILD- 被信号中断:返回-1, errno=EINTR |
<sys/wait.h> |
1. 阻塞等待:父进程暂停执行,直到有子进程退出 2. 若有多个子进程,仅回收第一个退出的子进程 3. 可通过宏解析 wstatus:- WIFEXITED(wstatus):是否正常退出- WEXITSTATUS(wstatus):获取正常退出的返回值- WIFSIGNALED(wstatus):是否被信号杀死 |
pid_t waitpid(pid_t pid, int *wstatus, int options) |
指定回收某个或某组子进程,支持阻塞/非阻塞模式,比wait更灵活;可避免父进程长时间阻塞 |
- pid:pid_t,指定回收的子进程:- pid > 0:回收PID为pid的子进程- pid = -1:回收任意子进程(同wait)- pid = 0:回收与父进程同组的子进程- pid < -1:回收组ID为-pid的子进程- wstatus:int*,存储退出状态(同wait)- options:int,选项:- 0:阻塞等待- WNOHANG:非阻塞,无僵尸子进程则立即返回0 |
成功: - 阻塞模式:返回回收的子进程PID - 非阻塞模式:有子进程回收则返回PID,无则返回0 失败:返回-1,并设置 errno |
<sys/wait.h> |
1. 比wait更灵活,可指定子进程和等待模式2. 常用场景:非阻塞轮询回收子进程( waitpid(-1, NULL, WNOHANG)) |
int execl(const char *path, const char *arg, ...) |
加载并执行指定路径的程序,替换当前进程的代码段和数据段(PID不变);参数以NULL结尾 |
- path:const char*,要执行的程序路径(如"/bin/ls")- arg:const char*,程序的第一个参数(通常为程序名)- ...:可变参数,后续参数为程序的命令行参数,以(char*)NULL结尾 |
成功:不返回(程序替换当前进程内存空间) 失败:返回-1,并设置 errno |
<unistd.h> |
1. 替换当前进程的代码段和数据段,PID不变 2. 若执行成功,后续代码不执行;仅失败时返回 3. 示例: execl("/bin/ls", "ls", "-l", NULL)执行ls -l |
int execlp(const char *file, const char *arg, ...) |
加载并执行程序,自动搜索PATH环境变量查找程序路径;参数以NULL结尾,无需手动指定完整路径 |
- file:const char*,程序名(如"ls"),自动搜索PATH环境变量- arg及...:同execl |
成功:不返回 失败:返回-1,并设置 errno |
<unistd.h> |
1. 区别于execl:无需指定完整路径,自动搜索PATH(如execlp("ls", "ls", "-l", NULL))2. 若 file含/,则按路径查找(同execl) |
int system(const char *command) |
创建子进程执行指定的系统命令,父进程阻塞等待命令执行完毕;命令输出默认到标准输出 | - command:const char*,要执行的系统命令字符串(如"ls -l") |
成功:返回命令的退出状态(需用WEXITSTATUS解析)失败:返回-1,并设置 errno |
<stdlib.h> |
1. 内部创建子进程执行命令,父进程阻塞等待 2. 命令执行结果输出到标准输出(屏幕) 3. 不适用于需交互的命令(如 "vi") |
FILE *popen(const char *command, const char *type) |
创建管道和子进程,执行系统命令;通过管道实现父进程与子进程的通信(读命令输出或写命令输入) | - command:const char*,系统命令字符串- type:const char*,管道方向:- "r":读取命令的输出(子进程stdout -> 父进程)- "w":向命令输入数据(父进程 -> 子进程stdin) |
成功:返回指向管道的文件指针(FILE*) 失败:返回 NULL,并设置errno |
<stdio.h> |
1. 创建管道和子进程,执行命令,返回文件指针用于读写 2. 需用 pclose关闭,pclose会等待命令执行完毕3. 示例: FILE *fp = popen("ls -l", "r");读取ls -l的输出 |
int pclose(FILE *stream) |
关闭popen创建的管道文件指针,等待子进程(命令)执行完毕,回收子进程资源 |
- stream:FILE*,popen返回的文件指针 |
成功:返回命令的退出状态 失败:返回-1,并设置 errno |
<stdio.h> |
1. 关闭管道,等待子进程退出 2. 不可用 fclose替代(fclose不等待子进程) |
void exit(int status) |
终止当前进程,刷新所有打开的流缓冲区,关闭文件,释放进程资源;调用终止处理函数 | - status:int,进程退出状态(0表示正常,非0表示异常) |
无返回值 | <stdlib.h> |
1. 刷新所有打开的流缓冲区,关闭文件,释放资源 2. 调用注册的终止处理函数( atexit注册)3. 区别于 _exit:_exit不刷新缓冲区,直接终止 |
void _exit(int status) |
立即终止当前进程,不刷新缓冲区,不调用终止处理函数,直接释放内核资源 | - status:int,退出状态 |
无返回值 | <unistd.h> |
1. 立即终止进程,不刷新缓冲区,不调用终止处理函数 2. 常用于子进程(避免刷新父进程的缓冲区) |
线程操作函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) |
创建新线程,指定线程执行函数和参数;新线程与主线程并发执行,共享进程资源 | - thread:pthread_t*,存储新线程的TID(线程ID)- attr:const pthread_attr_t*,线程属性(NULL表示默认属性)- start_routine:void*(*)(void*),线程函数指针(函数返回void,参数为void)- arg:void*,传递给线程函数的参数(需强制类型转换) |
成功:返回0 失败:返回错误码(非-1,需用 strerror打印错误) |
<pthread.h> |
1. 编译需加-lpthread选项(如gcc test.c -o test -lpthread)2. 线程函数返回的void*需为全局/堆变量(避免栈变量销毁) 3. 线程默认joinable(需 pthread_join回收) |
void pthread_exit(void *retval) |
终止当前线程,释放线程的栈资源;返回值通过pthread_join传递给回收线程 |
- retval:void*,线程返回值(传递给pthread_join) |
无返回值 | <pthread.h> |
1. 终止当前线程,释放线程资源(但进程资源需pthread_join回收)2. retval不可为栈变量(线程退出后栈释放) |
int pthread_join(pthread_t thread, void **retval) |
阻塞等待指定线程退出,回收线程资源,获取线程返回值;仅支持joinable状态的线程 | - thread:pthread_t,要回收的线程TID- retval:void**,存储线程返回值(pthread_exit的参数);若为NULL,不关心返回值 |
成功:返回0 失败:返回错误码 |
<pthread.h> |
1. 阻塞等待:调用线程暂停,直到thread线程退出2. 仅能回收joinable状态的线程;detach状态的线程不可join 3. 示例: pthread_join(tid, (void**)&ret);获取线程返回值ret |
int pthread_detach(pthread_t thread) |
将指定线程设置为detach状态,线程退出后自动释放资源,无需pthread_join回收 |
- thread:pthread_t,要设置为detach状态的线程TID |
成功:返回0 失败:返回错误码 |
<pthread.h> |
1. 设置线程为detach状态,退出后自动释放资源(无需pthread_join)2. 不可对已join的线程调用(会失败) 3. 也可在创建时通过属性设置detach( pthread_attr_setdetachstate) |
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) |
初始化互斥锁,用于保护多线程共享的临界资源,避免线程竞争导致的数据不一致 | - mutex:pthread_mutex_t*,互斥锁变量- attr:const pthread_mutexattr_t*,互斥锁属性(NULL为默认属性) |
成功:返回0 失败:返回错误码 |
<pthread.h> |
1. 互斥锁用于保护临界资源(多线程共享数据) 2. 也可静态初始化: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
int pthread_mutex_lock(pthread_mutex_t *mutex) |
获取互斥锁,若锁已被占用则阻塞等待;成功获取后进入临界区,确保临界区代码独占执行 | - mutex:pthread_mutex_t*,互斥锁变量 |
成功:返回0(获取锁) 失败:返回错误码 |
<pthread.h> |
1. 阻塞等待:若锁已被占用,线程暂停,直到锁释放 2. 临界区代码需放在 lock和unlock之间,避免竞争 |
int pthread_mutex_unlock(pthread_mutex_t *mutex) |
释放互斥锁,允许其他等待锁的线程竞争获取;仅持有锁的线程可释放 | - mutex:pthread_mutex_t*,互斥锁变量 |
成功:返回0(释放锁) 失败:返回错误码 |
<pthread.h> |
1. 仅持有锁的线程可释放(其他线程释放会失败) 2. 释放后,等待锁的线程竞争获取 |
信号操作函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler) |
为指定信号注册处理函数,定义信号的响应方式(忽略、默认处理、自定义处理) | - signum:int,信号值(如SIGINT(2)、SIGCHLD(17))- handler:sighandler_t,信号处理函数:- SIG_IGN:忽略该信号- SIG_DFL:默认处理(如SIGINT默认终止进程)- 自定义函数: void func(int sig)(sig为信号值) |
成功:返回之前的信号处理函数指针 失败:返回 SIG_ERR(-1),并设置errno |
<signal.h> |
1. 常用信号: - SIGINT(2):Ctrl+C触发,默认终止- SIGCHLD(17):子进程退出触发,默认忽略- SIGKILL(9)、SIGSTOP(19):不可捕获、忽略2. 自定义处理函数执行时,会自动屏蔽当前信号(避免重入) |
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) |
修改进程的信号阻塞集,实现信号的屏蔽(暂不处理)或解除屏蔽(恢复处理) | - how:int,操作类型:- SIG_BLOCK:将set中的信号添加到阻塞集- SIG_UNBLOCK:从阻塞集中删除set中的信号- SIG_SETMASK:用set替换阻塞集- set:const sigset_t,要操作的信号集;若为NULL,仅获取当前阻塞集- oldset:sigset_t,存储原阻塞集;若为NULL,不保存 |
成功:返回0 失败:返回-1,并设置 errno |
<signal.h> |
1. 信号集操作需配合以下函数: - sigemptyset:清空信号集- sigaddset:添加信号到集- sigismember:检查信号是否在集2. 阻塞的信号不会被丢弃,解除阻塞后会被处理 |
int sigemptyset(sigset_t *set) |
初始化信号集,将信号集清空(不包含任何信号),为后续添加信号做准备 | - set:sigset_t*,要清空的信号集 |
成功:返回0 失败:返回-1,并设置 errno |
<signal.h> |
初始化信号集为空(无任何信号) |
int sigaddset(sigset_t *set, int signum) |
将指定信号添加到信号集中,用于构建需要操作的信号集合(如阻塞、解除阻塞) | - set:sigset_t*,信号集- signum:int,要添加的信号值 |
成功:返回0 失败:返回-1,并设置 errno |
<signal.h> |
向信号集中添加指定信号 |
int sigismember(const sigset_t *set, int signum) |
检查指定信号是否包含在信号集中,用于判断信号是否处于阻塞或待处理状态 | - set:const sigset_t*,信号集- signum:int,要检查的信号值 |
成功: - 信号在集中:返回1 - 信号不在集中:返回0 失败:返回-1,并设置 errno |
<signal.h> |
判断信号是否在指定信号集中 |
其他基础函数
| 函数原型 | 功能描述 | 参数说明 | 返回值说明 | 头文件 | 关键注意事项 |
|---|---|---|---|---|---|
int printf(const char *format, ...) |
按指定格式将可变参数数据输出到标准输出(屏幕),等价于fprintf(stdout, format, ...) |
- format:const char*,格式控制字符串- ...:可变参数,与format的格式符对应 |
成功:返回实际输出的字节数 失败:返回负数 |
<stdio.h> |
1. 等价于fprintf(stdout, format, ...)2. 标准输出默认行缓冲,加 \n或fflush(stdout)可刷新 |
int scanf(const char *format, ...) |
按指定格式从标准输入(键盘)读取数据,存储到指定变量,等价于fscanf(stdin, format, ...) |
- format:const char*,格式控制字符串- ...:可变参数,需传变量地址(如&a) |
成功:返回成功赋值的参数个数 失败/EOF:返回 EOF |
<stdio.h> |
1. 等价于fscanf(stdin, format, ...)2. 读取字符串用 %s,遇空白符停止;需确保缓冲区足够大 |
int getchar(void) |
从标准输入(键盘)读取单个字符,等价于fgetc(stdin),支持字符级输入 |
无参数 | 成功:返回读取的字符(ASCII值) 失败/EOF:返回 EOF |
<stdio.h> |
1. 等价于fgetc(stdin)2. 每次读取1个字符,包括换行符 \n |
int putchar(int c) |
向标准输出(屏幕)写入单个字符,等价于fputc(c, stdout),支持字符级输出 |
- c:int,要输出的字符(ASCII值) |
成功:返回输出的字符 失败:返回 EOF |
<stdio.h> |
1. 等价于fputc(c, stdout)2. 每次输出1个字符 |
int access(const char *pathname, int mode) |
检查指定文件是否存在,以及当前进程对文件的访问权限(读、写、执行) | - pathname:const char*,文件路径/名称- mode:int,检查的权限:- F_OK:检查文件是否存在- R_OK:检查是否可读- W_OK:检查是否可写- X_OK:检查是否可执行 |
成功:所有检查的权限都满足,返回0 失败:至少一个权限不满足,返回-1,并设置 errno |
<unistd.h> |
1. 检查当前进程对文件的权限(基于进程的UID/GID) 2. 示例:`access("test.txt", F_OK |

浙公网安备 33010602011771号