文章目录
- C 标准库是一组 C 内置函数、常量和头文件,比如 <stdio.h>、<stdlib.h>、<math.h>,等等。这个标准库可以作为 C 程序员的参考手册。
- 标准库所在路径:
/usr/include
一、assert.h
- C 标准库的 assert.h 头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设不成立时在标准错误 stderr 上显示错误消息,并中止程序执行
- assert 只有在 Debug 版本中才有效,如果编译为 Release 版本则被忽略
// assert 的宏定义
# define assert(expr) \
((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
if (expr) \
; /* empty */ \
else \
__assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \
}))
# endif
// assert 使用示例
#include <stdio.h>
#include <assert.h>
int main() {
int a;
printf("请输入一个大于 10 的整数:");
scanf("%d", &a);
assert(a > 10); // 如果输入小于 10 的整数,则会报错:main.c:9: main: Assertion `a > 10' failed.
printf("输入的整数是:%d\n", a);
return (0);
}
二、ctype.h
C 标准库的 ctype.h 头文件提供了一些宏函数,可用于判断字符类型和字符类型转换
#include <stdio.h>
#include <ctype.h>
int main() {
int var1 = 'd';
int var2 = '2';
int i = 0;
char str[] = "hello";
if (isalpha(var1)) {
printf("var1 = |%c| 是一个字母\n", var1); // var1 = |d| 是一个字母
} else {
printf("var1 = |%c| 不是一个字母\n", var1);
}
if (isalpha(var2)) {
printf("var2 = |%c| 是一个字母\n", var2);
} else {
printf("var2 = |%c| 不是一个字母\n", var2); // var2 = |2| 不是一个字母
}
while (str[i]) {
putchar(toupper(str[i])); // HELLO
i++;
}
return (0);
}
// 判断字符类型
int isalnum(int c) // 检查所传的字符是否是字母和数字
int isalpha(int c) // 检查所传的字符是否是字母
int islower(int c) // 检查所传的字符是否是小写字母
int isupper(int c) // 检查所传的字符是否是大写字母
int ispunct(int c) // 检查所传的字符是否是标点符号字符
int isgraph(int c) // 检查所传的字符是否有图形表示法(字母数字字符和标点符号字符的集合)
int isdigit(int c) // 检查所传的字符是否是十进制数字
int isxdigit(int c) // 检查所传的字符是否是十六进制数字
int isspace(int c) // 检查所传的字符是否是空白字符(制表符、换行符、垂直制表符、换页符、回车符、空格符的集合)
int iscntrl(int c) // 检查所传的字符是否是控制字符
int isprint(int c) // 检查所传的字符是否是可打印的
// 字符大小写相互转换
int tolower(int c) // 把大写字母转换为小写字母
int toupper(int c) // 把小写字母转换为大写字母
三、time.h
定义了一些时间相关的变量和函数
// 变量
size_t:是无符号整数类型,它是 sizeof 关键字的结果
clock_t:这是一个适合存储处理器时间的类型
time_t:这是一个适合存储日历时间类型
struct tm:这是一个用来保存时间和日期的结构
struct tm {
int tm_sec; // 秒,范围从 0 到 59
int tm_min; // 分,范围从 0 到 59
int tm_hour; // 小时,范围从 0 到 23
int tm_mday; // 一月中的第几天,范围从 1 到 31
int tm_mon; // 月,范围从 0 到 11
int tm_year; // 自 1900 年起的年数
int tm_wday; // 一周中的第几天,范围从 0 到 6
int tm_yday; // 一年中的第几天,范围从 0 到 365
int tm_isdst; // 夏令时
};
// 函数
char *asctime(const struct tm *timeptr) // 返回一个指向字符串的指针,它代表了结构 timeptr 的日期和时间
clock_t clock(void) // 返回程序执行起(一般为程序的开头),处理器时钟所使用的时间
char *ctime(const time_t *timer) // 返回一个表示当地时间的字符串,当地时间是基于参数 timer
double difftime(time_t time1, time_t time2) // 返回 time1 和 time2 之间相差的秒数 (time1-time2)
struct tm *gmtime(const time_t *timer) // timer 的值被分解为 tm 结构,并用协调世界时(UTC)也被称为格林尼治标准时间(GMT)表示
struct tm *localtime(const time_t *timer) // timer 的值被分解为 tm 结构,并用本地时区表示
time_t mktime(struct tm *timeptr) // 把 timeptr 所指向的结构转换为一个依据本地时区的 time_t 值
size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) // 根据 format 中定义的格式化规则,格式化结构 timeptr 表示的时间,并把它存储在 str 中
time_t time(time_t *timer) // 计算当前日历时间,并把它编码成 time_t 格式
/*************************** 处理器时间统计 ***************************/
#include <stdio.h>
#include <sys/time.h> // #include "time.h"
// 返回无符号整形 us
unsigned int get_current_time() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec; // us
}
int main() {
unsigned int start_time = get_current_time();
int i = 10000000;
while (i--);
unsigned int end_time = get_current_time();
printf("elapsed_time = %.2f ms\n", (end_time - start_time) / 1000.0); // elapsed_time = 11.43 ms
return 0;
}
四、math.h
定义了各种数学函数,都带有一个 double 类型的参数,且都返回 double 类型的结果
double acos(double x) // 返回以弧度表示的 x 的反余弦
double asin(double x) // 返回以弧度表示的 x 的反正弦
double atan(double x) // 返回以弧度表示的 x 的反正切
double atan2(double y, double x) // 返回以弧度表示的 y/x 的反正切。y 和 x 的值的符号决定了正确的象限
double cos(double x) // 返回弧度角 x 的余弦
double cosh(double x) // 返回 x 的双曲余弦
double sin(double x) // 返回弧度角 x 的正弦
double sinh(double x) // 返回 x 的双曲正弦
double tanh(double x) // 返回 x 的双曲正切
double exp(double x) // 返回 e 的 x 次幂的值
double frexp(double x, int *exponent) // 把浮点数 x 分解成尾数和指数。返回值是尾数,并将指数存入 exponent 中。所得的值是 x = mantissa * 2 ^ exponent
double ldexp(double x, int exponent) // 返回 x 乘以 2 的 exponent 次幂
double log(double x) // 返回 x 的自然对数(基数为 e 的对数)
double log10(double x) // 返回 x 的常用对数(基数为 10 的对数)
double modf(double x, double *integer) // 返回值为小数部分(小数点后的部分),并设置 integer 为整数部分
double pow(double x, double y) // 返回 x 的 y 次幂
double sqrt(double x) // 返回 x 的平方根
double ceil(double x) // 返回大于或等于 x 的最小的整数值
double fabs(double x) // 返回 x 的绝对值
double floor(double x) // 返回小于或等于 x 的最大的整数值
double fmod(double x, double y) // 返回 x 除以 y 的余数
#define KD_Epsilon 1e-8
#ifndef KD_Equal
#define KD_Equal(a, b) ((fabs((a) - (b))) < (KD_Epsilon))
#endif
double a = 3.15;
double b = 3.1500001;
if KD_Equal(a, b) {
printf("equal");
} else {
printf("not equal");
}
五、stdio.h
标准输入、输出、错误流
List of functions:
Function Description
──────────────────────────────────────────────────────────────────────
clearerr(3) check and reset stream status
fclose(3) close a stream
fdopen(3) stream open functions
feof(3) check and reset stream status
ferror(3) check and reset stream status
fflush(3) flush a stream
fgetc(3) get next character or word from input stream
fgetpos(3) reposition a stream
fgets(3) get a line from a stream
fileno(3) return the integer descriptor of the argument stream
fopen(3) stream open functions
fprintf(3) formatted output conversion
fpurge(3) flush a stream
fputc(3) output a character or word to a stream
fputs(3) output a line to a stream
fread(3) binary stream input/output
freopen(3) stream open functions
fscanf(3) input format conversion
fseek(3) reposition a stream
fsetpos(3) reposition a stream
ftell(3) reposition a stream
fwrite(3) binary stream input/output
getc(3) get next character or word from input stream
getchar(3) get next character or word from input stream
gets(3) get a line from a stream
getw(3) get next character or word from input stream
mktemp(3) make temporary filename (unique)
perror(3) system error messages
printf(3) formatted output conversion
putc(3) output a character or word to a stream
putchar(3) output a character or word to a stream
puts(3) output a line to a stream
putw(3) output a character or word to a stream
remove(3) remove directory entry
rewind(3) reposition a stream
scanf(3) input format conversion
setbuf(3) stream buffering operations
setbuffer(3) stream buffering operations
setlinebuf(3) stream buffering operations
setvbuf(3) stream buffering operations
sprintf(3) formatted output conversion
sscanf(3) input format conversion
strerror(3) system error messages
sys_errlist(3) system error messages
sys_nerr(3) system error messages
tempnam(3) temporary file routines
tmpfile(3) temporary file routines
tmpnam(3) temporary file routines
ungetc(3) un-get character from input stream
vfprintf(3) formatted output conversion
vfscanf(3) input format conversion
vprintf(3) formatted output conversion
vscanf(3) input format conversion
vsprintf(3) formatted output conversion
vsscanf(3) input format conversion
六、stdlib.h
定义了一些通用的工具函数
double atof(const char *str) // 把参数 str 所指向的字符串转换为一个浮点数
int atoi(const char *str) // 把参数 str 所指向的字符串转换为一个整数
long int atol(const char *str) //把参数 str 所指向的字符串转换为一个长整数
double strtod(const char *str, char **endptr) // 把参数 str 所指向的字符串转换为一个浮点数
long int strtol(const char *str, char **endptr, int base) // 把参数 str 所指向的字符串转换为一个长整数
unsigned long int strtoul(const char *str, char **endptr, int base) // 把参数 str 所指向的字符串转换为一个无符号长整数
void *calloc(size_t nitems, size_t size) // 分配所需的内存空间,并返回一个指向它的指针
void free(void *ptr) // 释放之前调用 calloc、malloc 或 realloc 所分配的内存空间。
void *malloc(size_t size) // 分配所需的内存空间,并返回一个指向它的指针。
void *realloc(void *ptr, size_t size) // 尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小
void abort(void) // 使一个异常程序终止
void exit(int status) // 使程序正常终止
char *getenv(const char *name) // 搜索 name 所指向的环境字符串,并返回相关的值给字符串
int system(const char *string) // 由 string 指定的命令传给要被命令处理器执行的主机环境
void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)) // 执行二分查找
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) // 数组排序
int abs(int x) // 返回 x 的绝对值
div_t div(int numer, int denom) // 分子除以分母
long int labs(long int x) // 返回 x 的绝对值
ldiv_t ldiv(long int numer, long int denom) // 分子除以分母
int mblen(const char *str, size_t n) // 返回参数 str 所指向的多字节字符的长度
七、stddef .h
stddef .h 头文件定义了各种 变量类型和宏,这些定义中的大部分也出现在其它头文件中(例如 stdio.h 中也定义了 size_t 和 NULL)
// stddef.h 中定义的变量类型
size_t:无符号整数类型,它是 sizeof 关键字的结果(可以理解为 unsignted int size,当 unsignted int 用就可以了)
ptrdiff_t:有符号整数类型,它是两个指针相减的结果
wchar_t:宽字符常量大小的整数类型
// stddef.h 中定义的宏
NULL:空指针常量的值
offsetof(type, member-designator):会生成一个类型为 size_t 的整型常量,
它是一个结构成员相对于结构开头的字节偏移量。成员是由 member-designator 给定的,结构的名称是在 type 中给定的
#include <stddef.h>
#include <stdio.h>
struct address {
char name[50];
char street[36];
int phone;
};
int main() {
// address 结构中的 name 偏移 = 0 字节
printf("address 结构中的 name 偏移 = %lu 字节\n",
offsetof(struct address, name));
// address 结构中的 street 偏移 = 50 字节
printf("address 结构中的 street 偏移 = %lu 字节\n",
offsetof(struct address, street));
// address 结构中的 phone 偏移 = 88 字节(存在字节对齐)
printf("address 结构中的 phone 偏移 = %lu 字节\n",
offsetof(struct address, phone));
return (0);
}
10、dirent.h
11、fcntl.h
12、threads.h
13、pthread.h
并发编程接口:C11 标准后,C 语言为我们专门提供了一套通用的并发编程接口
threads.h
中包含有与线程控制、互斥量、条件变量,以及线程本地存储相关的接口;stdatomic.h
中则包含有与原子操作相关的接口