2、C 常用标准库简介

本文介绍了C标准库中的assert.h、ctype.h、time.h、math.h、stdio.h、stdlib.h、stddef.h等重要头文件的功能,包括assert断言、字符类型判断、时间处理、数学运算、I/O操作和通用工具。通过实例演示了如何在实际编程中运用这些库进行程序开发和错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  • 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 中则包含有与原子操作相关的接口

14、sched.h


15、semaphore.h


16、参考资料

C 标准库 - 参考手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值