C语言的库文件包括:std开头的标准库、assert断言、sys开头的系统库、string字符串、time时间、math数学运算、pthread线程等。其中,标准库有stdalign.h、stdarg.h、stdatomic.h、stdbool.h、stddef.h、stdint.h、stdio.h、stdlib.h。系统库有sys/mman.h、sys/stat.h、sys/ioctl.h、sys/file.h。详细的库文件如下表所示:
assert.h | limits.h | stdatomic.h | time.h | sys/ioctl.h | complex.h | locale.h | stdbool.h | uchar.h | sys/file.h | ctype.h | math.h | stddef.h | wchar.h | unistd.h | errno.h | setjmp.h | stdint.h | wctype.h | pthread.h | fenv.h | signal.h | stdio.h | fcntl.h | | float.h | stdalign.h | stdlib.h | sys/mman.h | | inttypes.h | stdarg.h | string.h | sys/stat.h | |
目录
1、assert.h断言
2、ctype.h字符串分类
3、errno.h错误码
4、inttypes.h整数类型
5、limits.h最大值与最小值
6、math.h数学运算
7、setjmp.h长跳转
8、dlfcn.h库操作
9、pthread线程操作
10、Unix标准unistd.h
11、time.h系统时间
1、assert.h断言
assert是c语言库提供的断言,只有一个参数,用于判断结果是否符合预期。示例代码如下:
assert(a > 0);
2、ctype.h字符串分类
ctype用于ASCII字符串分类,用于判断是否为大小写字母、数字、转义字符、转为大写字母、转为小写字母等操作。源码示例如下:
// 是否为大小写字母或数字
int isalnum(int __ch);
// 是否为[A-Za-z]的大小写字母
int isalpha(int __ch);
// 是否为空格键或tab键
int isblank(int __ch);
// 是否为控制字符
int iscntrl(int __ch);
// 是否为数字
int isdigit(int __ch);
// 是否为a-z的小写字母
int islower(int __ch);
// 是否为标点符号
int ispunct(int __ch);
// 是否为转移字符,例如:\f\n\r\t\v
int isspace(int __ch);
// 是否为A-Z的大写字母
int isupper(int __ch);
// 是否为十六进制0-9A-Fa-f的数字
int isxdigit(int __ch);
// 转换为小写字母
int tolower(int __ch);
// 转换为大写字母
int toupper(int __ch);
3、errno.h错误码
errno包含linux/errno.h标准错误码,比如io操作发生错误时,我们可以打印对应的错误信息:
printf("errno=%d\n", errno);
printf("err msg=%s\n", strerror(errno));
4、inttypes.h整数类型
inttypes提供整数类型的宏定义,包括:整型、有符号、无符号、八进制、十六进制,位数包括:8位、16位、32位以及64位。源码示例如下:
// 整型int的8位、16位、32位、64位
#define PRId8 "d" /* int8_t */
#define PRId16 "d" /* int16_t */
#define PRId32 "d" /* int32_t */
#define PRId64 __PRI_64_prefix"d" /* int64_t */
// 有符号int的8位、16位、32位、64位
#define PRIi8 "i" /* int8_t */
#define PRIi16 "i" /* int16_t */
#define PRIi32 "i" /* int32_t */
#define PRIi64 __PRI_64_prefix"i" /* int64_t */
// 无符号int的8位、16位、32位、64位
#define PRIu8 "u" /* uint8_t */
#define PRIu16 "u" /* uint16_t */
#define PRIu32 "u" /* uint32_t */
#define PRIu64 __PRI_64_prefix"u" /* uint64_t */
// 十六进制int的8位、16位、32位、64位
#define PRIx8 "x" /* uint8_t */
#define PRIx16 "x" /* uint16_t */
#define PRIx32 "x" /* uint32_t */
#define PRIx64 __PRI_64_prefix"x" /* uint64_t */
例如打印输出64位的整型数:
int64_t num = 1010;
printf("num=%"PRId64"\n", num);
5、limits.h最大值与最小值
limits提供int、short、char、long类型最大值与最小值的宏定义,包括有符号与无符号。其中无符号最小值等于0,有符号最小值等于最大值相反数加1。源码定义如下:
// 有符号的char、short、int、long最大值
#define SCHAR_MAX __SCHAR_MAX__
#define SHRT_MAX __SHRT_MAX__
#define INT_MAX __INT_MAX__
#define LONG_MAX __LONG_MAX__
// 有符号的char、short、int、long最小值
#define SCHAR_MIN (-__SCHAR_MAX__-1)
#define SHRT_MIN (-__SHRT_MAX__ -1)
#define INT_MIN (-__INT_MAX__ -1)
#define LONG_MIN (-__LONG_MAX__ -1L)
// 无符号的char、short、int、long最大值
#define UCHAR_MAX (__SCHAR_MAX__*2 +1)
#define USHRT_MAX (__SHRT_MAX__ *2 +1)
#define UINT_MAX (__INT_MAX__ *2U +1U)
#define ULONG_MAX (__LONG_MAX__ *2UL+1UL)
// 无符号的char最大值与最小值
#define CHAR_MIN 0
#define CHAR_MAX UCHAR_MAX
// 64位long long最大值与最小值
#define LLONG_MAX __LONG_LONG_MAX__
#define LLONG_MIN (-__LONG_LONG_MAX__-1LL)
#define LONG_LONG_MAX __LONG_LONG_MAX__
#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1LL)
6、math.h数学运算
math提供常用的数学运算,包括:正弦/余弦/正切的三角函数、指数函数、对数函数、取绝对值、取模运算、向上取整、向下取整等。源码定义如下:
// 三角函数:正弦、余弦、正切
double cos(double __x);
double sin(double __x);
double tan(double __x);
// 反三角函数
double acos(double __x);
double asin(double __x);
double atan(double __x);
//双曲线三角函数
double cosh(double __x);
double sinh(double __x);
double tanh(double __x);
// 指数函数
double exp(double __x);
// 对数函数
double log(double __x);
double log10(double __x);
// 取绝对值
double fabs(double __x);
// x的y次幂
double pow(double __x, double __y);
// 开平方根
double sqrt(double __x);
// 向上取整
double ceil(double __x);
// 向下取整
double floor(double __x);
// 四舍五入
double round(double __x);
// 取模运算
double fmod(double __x, double __y);
7、setjmp.h长跳转
setjmp提供长跳转指令功能,与函数内的短跳转goto作用类似。示例代码如下:
#include <setjmp.h>
jmp_buf jump_buf;
void say_hello() {
longjmp(jump_buf, -1);
}
void hello() {
if (setjmp(jump_buf) != 0) {
printf("There is a error!\n");
}
say_hello();
}
8、dlfcn.h库操作
dlfcn提供对库文件操作,包括打开库、获取库函数、获取错误信息、关闭库等操作,示例代码如下:
void test_lib() {
void *ptr = dlopen("libc", RTLD_LAZY);
if (!ptr)
return;
void (*func)() = dlsym(ptr, "printf");
(*func)("hello,world!\n");
dlclose(ptr);
}
9、pthread线程操作
pthread是POSIX提供的线程,包括线程、互斥锁和条件变量三个部分。其中,线程有创建、分离、等待、退出等操作,互斥锁有初始化、上锁/解锁、销毁操作,条件变量有初始化、等待、通知、销毁操作。源码定义如下:
// 创建线程
int pthread_create(pthread_t* pthread_ptr, pthread_attr_t const* attr, void* (*start_routine)(void*), void*);
// 分离线程独立运行,不受调用线程控制
int pthread_detach(pthread_t pthread);
// 阻塞调用线程,等待本线程执行完成
int pthread_join(pthread_t pthread, void** return_value_ptr);
// 退出线程
void pthread_exit(void* return_value);
// 条件变量初始化
int pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr);
// 条件变量等待
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
// 条件变量超时等待
int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const struct timespec* timeout);
// 信号通知
int pthread_cond_signal(pthread_cond_t* cond);
// 广播通知
int pthread_cond_broadcast(pthread_cond_t* cond);
// 条件变量销毁
int pthread_cond_destroy(pthread_cond_t* cond);
// 互斥锁初始化
int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);
// 互斥锁上锁
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_trylock(pthread_mutex_t* mutex);
// 互斥锁解锁
int pthread_mutex_unlock(pthread_mutex_t* mutex);
// 互斥锁销毁
int pthread_mutex_destroy(pthread_mutex_t* mutex);
创建线程,并且实现多线程通信,先打印奇数再打印偶数,代码如下:
int odd_finish = 0;
pthread_cond_t cond;
pthread_mutex_t mutex;
void* odd_task(void *arg) {
pthread_mutex_lock(&mutex);
for (int i=0; i<100; i++) {
if (i % 2 == 1) {
printf("odd=%d\n", i);
}
}
odd_finish = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return nullptr;
}
void* even_task(void *arg) {
pthread_mutex_lock(&mutex);
while (!odd_finish) {
pthread_cond_wait(&cond, &mutex);
}
for (int i=0; i<100; i++) {
if (i % 2 == 0) {
printf("even=%d\n", i);
}
}
pthread_mutex_unlock(&mutex);
return nullptr;
}
void execute_task() {
pthread_t work_thread1;
pthread_t work_thread2;
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_create(&work_thread1, NULL, odd_task, NULL);
pthread_join(work_thread1, NULL);
pthread_create(&work_thread2, NULL, even_task, NULL);
pthread_join(work_thread2, NULL);
}
10、Unix标准unistd.h
unistd作为Unix标准,提供POSIX操作系统的API,包括fork进程、创建管道、创建软链接、创建硬链接、系统级休眠、IO操作等,源码定义如下:
// fork进程:pid_t=0为子进程,pid_t=0为父进程
pid_t fork(void);
// 获取进程id
pid_t getpid(void);
// 获取线程id
pid_t setsid(void);
// 退出进程,清理内存
void _exit(int __status);
// 改变进程优先级,数值越大优先级越低
int nice(int __incr);
// 创建硬链接到当前路径
int link(const char* __old_path, const char* __new_path);
// 创建软链接到当前路径
int symlink(const char* __old_path, const char* __new_path);
// 修改目录
int chdir(const char* __path);
// 移除目录
int rmdir(const char* __path);
// 创建管道,fds[0]为管道读取端,fds[1]为管道写入端
int pipe(int __fds[2]);
// 修改属组所有权
int chown(const char* __path, uid_t __owner, gid_t __group);
// IO的读写、关闭操作
int close(int __fd);
ssize_t read(int __fd, void* __buf, size_t __count);
ssize_t write(int __fd, const void* __buf, size_t __count);
// 64系统的seek、read、write操作
off64_t lseek64(int __fd, off64_t __offset, int __whence);
ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset);
ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset);
// 定时器,以秒为单位
unsigned int alarm(unsigned int __seconds);
// 休眠,为秒为单位
unsigned int sleep(unsigned int __seconds);
// 休眠,以微秒为单位
int usleep(useconds_t __microseconds);
// 系统调用
long syscall(long __number, ...);
11、time.h系统时间
time提供系统级别的时间,有一个tm结构体,包括年月日、时分秒、时区,结构体如下:
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
long int tm_gmtoff;
const char* tm_zone;
};
时钟时间的源码函数定义如下:
// 处理器时钟
clock_t clock(void);
// 系统当前时间戳
time_t time(time_t* __t);
// 日历时间,返回字符串
char* ctime(const time_t* __t);
// 日期时间,转为ascii码
char* asctime(const struct tm* __tm);
// 两个时间差值
double difftime(time_t __lhs, time_t __rhs);
// tm转为time_t
time_t mktime(struct tm* __tm);
// 本地时间
struct tm* localtime(const time_t* __t);
// time_t转为tm
struct tm* gmtime(const time_t* __t);
// 时间格式化
char* strptime(const char* __s, const char* __fmt, struct tm* __tm);
时间戳、日历时间、格式化时间,代码示例如下:
time_t current_time = time(nullptr);
printf("current timestamp=%ld\n", current_time);
struct tm* tm = localtime(¤t_time);
char *ascii_time = asctime(tm);
printf("ascii time=%s\n", ascii_time);
char *calendar_time = ctime(¤t_time);
printf("calendar time=%s\n", calendar_time);
char timestamp[256];
strftime(timestamp, 256, "%Y-%m-%d_%H:%M:%S", tm);
printf("timestamp format=%s\n", timestamp);
打印出来的时间如下:
current timestamp = 1653624175
ascii time = Fri May 27 12:02:55 2022
calendar time = Fri May 27 12:02:55 2022
timestamp format = 2022-05-27_12:02:55
|