C语言最佳实践之库文件介绍(上)

C语言的库文件包括:pthread线程、assert断言、string字符串、time时间、math数学运算、std开头的标准库、sys开头的系统库等。其中,标准库有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.hlimits.hstdatomic.htime.hsys/ioctl.h
complex.hlocale.hstdbool.huchar.hsys/file.h
ctype.hmath.hstddef.hwchar.hunistd.h
errno.hsetjmp.hstdint.hwctype.hpthread.h
fenv.hsignal.hstdio.hfcntl.h
float.hstdalign.hstdlib.hsys/mman.h
inttypes.hstdarg.hstring.hsys/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);

创建线程,并且实现多线程通信,共享变量交替打印从0到100,代码如下:

int num = 0;
int odd_flag = 0;
pthread_cond_t cond;
pthread_mutex_t mutex;

void* odd_task(void *arg)
{ 
    for (int i=0; i<50; i++) {
        pthread_mutex_lock(&mutex);
        while (!odd_flag) {
            pthread_cond_wait(&cond, &mutex);
        }
        printf("odd  = %d\n", num++);
        odd_flag = 0;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}

void* even_task(void *arg)
{
    for (int i=0; i<50; i++) {
        pthread_mutex_lock(&mutex);
        while (odd_flag) {
            pthread_cond_wait(&cond, &mutex);
        }
        printf("even = %d\n", num++);
        odd_flag = 1;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}

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, even_task, NULL);
    pthread_create(&work_thread2, NULL, odd_task, NULL);
    pthread_join(work_thread1, 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(NULL);
    printf("current timestamp=%ld\n", current_time);
    struct tm* tm = localtime(&current_time);
    char *ascii_time = asctime(tm);
    printf("ascii time=%s\n", ascii_time);
    char *calendar_time = ctime(&current_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

听说这个有用 The following are typedefs of fundamental integral types or extended integral types. signed type unsigned type description intmax_t uintmax_t Integer type with the maximum width supported. int8_t uint8_t Integer type with a width of exactly 8, 16, 32, or 64 bits. For signed types, negative values are represented using 2's complement. No padding bits. Optional: These typedefs are not defined if no types with such characteristics exist.* int16_t uint16_t int32_t uint32_t int64_t uint64_t int_least8_t uint_least8_t Integer type with a minimum of 8, 16, 32, or 64 bits. No other integer type exists with lesser size and at least the specified width. int_least16_t uint_least16_t int_least32_t uint_least32_t int_least64_t uint_least64_t int_fast8_t uint_fast8_t Integer type with a minimum of 8, 16, 32, or 64 bits. At least as fast as any other integer type with at least the specified width. int_fast16_t uint_fast16_t int_fast32_t uint_fast32_t int_fast64_t uint_fast64_t intptr_t uintptr_t Integer type capable of holding a value converted from a void pointer and then be converted back to that type with a value that compares equal to the original pointer. Optional: These typedefs may not be defined in some library implementations.* Some of these typedefs may denote the same types. Therefore, function overloads should not rely on these being different. * Notice that some types are optional (and thus, with no portability guarantees). A particular library implementation may also define additional types with other widths supported by its system. In any case, if either the signed or the unsigned version is defined, both the signed and unsigned versions are defined.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐福记456

您的鼓励和肯定是我创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值