C语言标准库函数

 

标准库函数

整形函数

分为三类

  • 算数

  • 随机数

  • 字符串转换

算数<stdlib.h>

int abs(int value);//返回绝对值
long int labs(long int value);//返回绝对值
div_t div(int numerator, int denominator);//第二个参数除以第一个,返回商和余数
//返回值结构
int quot;//商,如果不能整除则是小于实际的结果的最大整数,为负数的时候不确定
int rem;//余数
ldiv_t div(long int number, long int deno)

随机数<stdlib.h>

int rand(void);
void srand(unsignde int seed);

rand返回一个范围在0到RAND_MAX的随机数,至少为32767

srand设置随机数srand((unsigned int)time(0));设置为时间

字符串转换<sdlib.h>

int atoi(char const *string);
long int atol(char const *string);
long int strtol(char const *string, char **unused, int base);
unsigned long int strtoul(char const *string, char **unused, int base);

atoi atol:转换的值以10为基数

strtol strtoul:转换的时候指定基数,在转换结束的时候把下一个字符的指针存放在unused之中,基数为0的时候任何用于书写整数的数字面值都会被书写,包括"0x234"这种,在基数为11-36的时候a-z被翻译为10-35

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 int main(void)
  5 {
  6     char *b;
  7     long int a;
  8     char **c = &b;
  9     a = strtol("590bear", c, 12);//e对于十二进制是非法的,返回的指针指向e
 10     printf("%ld\n", a);
 11     a = strtol("0x123", c, 0);
 12     printf("%ld\n", a);
 13     a = strtol("00101", c, 2);
 14     printf("%ld\n", a);
 15     return 0;
 16 }    
​
resule:
9947            //11+12*12*9+12*12*12*5
291
5
​

当返回值出错的时候会把错误传入erno,传入ERANGE,并返回错误标志

函数返回值
strtol返回值太大为负数,LONG_MIN,太大为正数,LONG_MAX
strtoul太大返回UNLONG_MAX

浮点型函数<math.h>

函数库中的返回值、参数大部分为double

定义域错误errno设置为EDOM

太大函数返回HUGE_VAL,太小返回0,有可能会把errno设置为ERANGE

三角函数

double sin(double angle);
double cos(double angle);
double tan(double angle);
double asin(double value);
double acos(double value);
double atan(double value);
double atan2(double x, double y);

sin cos tan的参数是一个用弧度表示得知,返回对应的值

asin acos atan返回的是反正弦函数,反余弦,反正切asin atan返回值是一个-π/2-π/2,cos的是0-π

atan2使用y/x的值求反正切的值,通过两个数的符号决定象限,返回值为-π-π

双曲函数

double sinh(double angle);
double cosh(double angle);
double tanh(double angle);

对数指数函数

double exp(double x);
double log(double x);
double log10(double x);

exp返回e的x次幂

log返回log以x的底数

log10以10为底数

浮点数表示

根据编译器格式存储一个浮点数

double frexp(double value, int *exponent);
double ldexp(double fraction,int exponent);
double modf(double value, double *ipart);

fraction X 2 ^ exponent = value

frexp返回fraction

ldexp返回value 用于在不能兼容浮点格式的机器之间传递信息

modf把一个小数分解为两部分,整数部分存储以第二个参数,小数部分返回值

double pcw(double x, double y);
double sqrt(double x);

pcw返回x的y次幂x^y,如果x是一个负数,y不是一个整数就会出现定义域错误

sqrt函数返回参数的平方根,为负数出现定义域错误

底数、顶数、绝对值和余数

double floor(double x);
double cell(double x);
double fabs(double x);
double fmod(double x, double y);

floor返回不大于这个数的最大整数

cell返回不小于的最小值

fabs返回其参数的绝对值

fmod返回x除以y的余数

字符转转换

double atof(char const *string);
double strtod(char const *string, char **unused);

参数前有空白直接忽略,然后把合法的字符转换为一个double,忽略结尾的非法字符

strtod会返回一个指向下一个参数的指针

没有合法的参数返回0,如果过大存储不下errno存储ERANGE这个值函数返回HUGE_VAL

日期和时间函数

处理时间<time.h>

clock_t clock(void);

这个值可能是一个近似值,如果要更精确的值,可以再main函数最开始调用,然后用两个数相减,如果机器不能提供时间,或者时间太大返回-1,程序开始执行到调用这个函数的时间

返回的是一个数字,是处理器滴答的次数, 转换为秒应该除以常量CLOCK_PER_SEC

当天时间

time_t time(time_t *retrun_value);

返回的时间通过这个指针传递, 时间太大的话返回-1,标准没有定义具体的格式,最好不要直接使用

时间日期的转换

char *ctime(time_t const *time_value);
double difftime(time_t time_t time2);

ctime 的参数是一个指向time_t的指针,返回的是一个字符串格式

  1 #include <stdio.h>                                                                    
  2 #include <time.h>
  3 #include <stdlib.h>
  4 int main(void)
  5 {
  6     char *a, *b;
  7     a = (char *)malloc(30);
  8     b=a;//地址备份用于释放内存
  9     time_t time_n;
 10     time(&time_n);
 11     a = ctime(&time_n);//这个时a的值会发生改变
 12     printf("%s", a);
 13     free(b);
 14     return 0;
 15 
 16 }

result:
Sat Jul 30 13:23:52 2022

difftime计算time1-time2的值,把结果转换为秒

struct tm *gmtime(time_t const *time_value);
struct tm *localtime(time_t const *time_value);

用来把time_t的格式转换为一个结构体

gmtime转为世界协调时间UTC

localtime转换为本地时间

tm结构体

类型范围含义
int tm_sec0-61分之后的秒数
int tm_min0-59小时之后的分钟数
int tm_hour0-23午夜之后的小时数
int tm_mday1-31当月的日期
int tm_mon0-111月后的月份,从零开始
int tm_year0-??1900年之后的年数
int tm_wday0-6星期日后的天数
int tm_yday0-365一月一日之后的天数
int tm_isdat夏令时标志
  1 #include <stdio.h>                                                                    
  2 #include <time.h>
  3 int main()
  4 {
  5     time_t time_n;
  6     struct tm *tp;
  7     time(&time_n);//获取时间
  8     tp = gmtime(&time_n);//时间转换为结构体
  9     printf("time: %s", ctime(&time_n));//转换为字符串
 10     printf("hour:%d\n", tp->tm_hour);
 11     printf("min:%d\n", tp->tm_min);
 12     printf("mday:%d\n", tp->tm_mday);
 13 }
result:
time: Sat Jul 30 15:26:22 2022

hour:15
min:26
mday:30
  • 结构体的操作

char *asctime(struct tm const *tm_ptr);
size_t strftime(char *string, size_t maxsize, char const *format, struct tm const *tm_ptr);

asctime把结构体转换为一个字符串,和ctime的格式一样

strftime把字符串转换为一个,字符串的长度小于maxsize,被复制到第一个参数,返回值为字符串的长度,当字符串长度大于maxsize返回-1

代码由……代替
%%一个%字符
%a星期的某一天,以当地星期几的格式简写
%A星期的某一天,以当地星期几的格式全写
%b月份,当地简写
%B全写
%c日期和时间使用%x和%X
%d一个月的第几天 0-31
%H小时24小时制 0-23
%I12小时制 0-12
%J一年的第几天 001-365
%m月份 01-12
%M分钟 00-59
%PAM或者PM
%S秒 0-61
%U第几个星期 周日为第一天
%w星期的第几天 0-6
%W第几个星期 周一为第一天
%x日期
%X时间
%y当前世纪的年数
%Y年份全写
%Z时区简写
  1 #include <stdio.h>                                                                    
  2 #include <stdlib.h>
  3 #include <time.h>
  4 int main(void)
  5 {
  6     time_t t;
  7     char *c, *b;
  8     struct tm *p;
  9     c = (char *)malloc(40);
 10     b=c;
 11     time(&t);
 12     p = localtime(&t);
 13 
 14     strftime(c, 40, "a = %a\n", p);
 15     printf("%s", c);
 16     strftime(c, 40, "A = %A\n", p);
 17     printf("%s", c);
 18     strftime(c, 40, "b = %b\n", p);
 19     printf("%s", c);
 20     strftime(c, 40, "B = %B\n", p);
 21     printf("%s", c);
 22     strftime(c, 40, "c = %c\n", p);
 23     printf("%s", c);
 24     strftime(c, 40, "d = %d\n", p);
 25     printf("%s", c);
 26     strftime(c, 40, "H = %H\n", p);
 27     printf("%s", c);
 28     strftime(c, 40, "I = %I\n", p);
 29     printf("%s", c);
 30     strftime(c, 40, "J = %J\n", p);
 31     printf("%s", c);
 32     strftime(c, 40, "m = %m\n", p);
 33     printf("%s", c);
 34     strftime(c, 40, "M = %M\n", p);
 35     printf("%s", c);
 36     strftime(c, 40, "P = %P\n", p);
 37     printf("%s", c);
 38     strftime(c, 40, "S = %S\n", p);
 39     printf("%s", c);
 40     strftime(c, 40, "U = %U\n", p);
 41     printf("%s", c);
 42     strftime(c, 40, "w = %w\n", p);
 43     printf("%s", c);
 44     strftime(c, 40, "W = %W\n", p);
 45     printf("%s", c);
 46     strftime(c, 40, "x = %x\n", p);
 47     printf("%s", c);
 48     strftime(c, 40, "X = %X\n", p);
 49     printf("%s", c);
 50     strftime(c, 40, "y = %y\n", p);
 51     printf("%s", c);
 52     strftime(c, 40, "Y = %Y\n", p);
 53     printf("%s", c);
 54     strftime(c, 40, "Z = %Z\n", p);
 55     printf("%s", c);
 56     
 57     free(b);
 58 
 59     
 60 }

result

a = Sat
A = Saturday
b = Jul
B = July
c = Sat Jul 30 15:58:04 2022
d = 30
H = 15
I = 03
J = %J  //出错没有这个参数
m = 07
M = 58
P = pm
S = 04
U = 30
w = 6
W = 30
x = 07/30/22
X = 15:58:04
y = 22
Y = 2022
Z = CST
time_t mktime(struct tm *tm_ptr);

把结构体转换为size_t格式

非本地跳转<setjmp.h>

类似于goto但是范围不限于一个函数的作用域之内,常用于深层函数嵌套链

int setjmp(jmp_buf state);
void longjmp(jump_buf state, int value);

声明一个jmp_buf的变量,使用setjmp对他初始化,返回值为0,同时把程序的状态进行保存,调用时候的函数成为顶层函数,之后使用longjmp函数进行返回

longjmp就是通过让执行流,通过再次从setjump返回,返回值是value,必须为一个非零的值

  1 #include <stdio.h>                                                                    
  2 #include <stdlib.h>
  3 #include <setjmp.h>
  4 
  5 jmp_buf restart;
  6 void func(void)
  7 {   
  8     printf("func\n");
  9     longjmp(restart, 1);
 10     printf("below\n");
 11 }
 12 int main(void)
 13 {
 14     int value;
 15     value = setjmp(restart);
 16     if(value == 0)
 17     {
 18         printf("value = 0\n");
 19         func();
 20     }
 21     else if(value == 1)
 22         printf("value =1\n");
 23     return 0;
 24 }
result:

value = 0
func
value =1

当顶层函数返回的时候,保存的状态就不再有效了

信号

大多数的事件发生都是由程序引发的,例如执行各种语句请求输入,但是有些事件不是由程序本身引起的,常见的例子就是用户中断程序,必须对这种事件做出反应

信号是一种事件,可能是异步发生的,通常默认是终止程序,但是可以设置

信号名<signed.h>

信号含 义
SIGABRT程序请求异常终止
SIGFPE算数错误
SIGILL检测到非法的指令
SIGSEGV检查内存的非法访问
SIGINT交互性注意信号
SIGTREM终止程序的请求

SIGABRT:abort函数引起

SIGFPE:上溢、下溢、除零

SIGILL:非法的CPU指令

SIGSEGV:访问不存在的地址,或者不属于程序的地址,以及地址没有对齐

SIGINT:用户中断程序,一般设置处理函数

SIGTREM:另一种用于处理中断的信号,一般不设置处理函数

处理信号<signed.h>

int raise(int sig);

可以主动引发一个信号,和自助引发的作用一样

void ( *signal(int sig, void(* hander)(int)))(int);

参数是一个信号名以及一个没有返回值, 接受一个整形函数的指针, 函数的返回参数是一个同样的指针

返回的是之前的处理函数的指针, 失败返回SIG_ERR

参数中的是要设置的指针

第二个参数SIG_DFL缺省处理,SIG_IGN忽略信号

信号处理函数

一个已经设置处理函数的信号发生的时候,首先系统恢复信号的缺省行为, 防止处理函数内部也发生这个信号导致无限循环,然后信号调用函数触发,信号代码为参数传递给函数

信号函数处理的情况是有限的,信号如果是异步的, 也就是说不是abrotraise引起的不要使用signal.h以外的库函数,而除了能给一个volatile sig_atomic_t的静态变量赋值以外无法访问其他静态变量

程序的其他地方检查变量的值,来确定是不是有信号产生

sig_atomic_t定义了一种CPU可以以原子的方式访问的数据类型, 也就是不可分割的访问单位, 因为访问不是这种数据的时候有中间步骤, 可能会产生新的信号

标准信号处理可以使用exit() abort()函数但是由于这两个是库函数, 所以当被异步处理的时候可能不能正常运行

volatile数据

信号的处理可能会发生在任何时候, 要处理的变量可能会在任何时候发生改变, 这个关键字告诉编译器防止他修改程序含义的方式优化程序

示例

if(value){
    printf("True");
}
else{
    printf("False");
}
if(value){
    printf("True");
}
else{
    printf("False");
}

可能会被优化为

if(value){
    printf("True");
    printf("True");
}
else{
    printf("False");
    printf("False");
}

但是由于信号可能在任何时候产生, 所以有可能导致结果的不同

信号处理函数返回

从信号处理函数返回到信号发生的地方, 例外是SIGFPE(计算出错),由于计算不能完成, 结果未知

如果希望再次捕捉同样的信号, 要在返回之前用signal函数重新设置

由于不同的机器处理方式不同, 有可能不会定义所有的符号, 有的也不会回到缺省的状态, 所以移植姓会降低

打印可变参数列表<stdarg.h>

int vprintf(char const *format, va_list arg);
int vfprintf(FILE *stream, char const *format, va_list arg);
int vfprintf(char *buffer, char const *format, va_list arg);

va_list必须用va_start初始化

执行环境

终止执行<stdlib.h>

void abort(void);
void atexit(void (func)(void));
void exit(int status);

abort不正常的终止一个正在运行的程序,引发信号

atexit用来把一些函数注册为退出函数.当函数正常终止的时候用(exit或者mainreturn),退出函数被调用,有多个的时候按照注册的顺序依次执行

exit调用之后注册的函数依次调用, 然后用于流的缓冲区刷新,所有打开的文件关闭,tmpfile创建的文件删除

  • 注:在注册的函数之中调用exit有可能会导致无限循环

断言<assert.h>

声明某种东西应该为真

void assert(int expression);

执行的时候对参数进行检测, 如果为假, 就向标准错误打印一条诊断信息然后终止程序

  1 #include <stdio.h>                                                                    
  2 #include <assert.h>
  3 
  4 int main(void)
  5 {
  6     assert(0);
  7     printf("hi\n");
  8     return 0;
  9 }



a.out: main5.c:6: main: Assertion `0' failed.
已放弃 (核心已转储)

可以通过这个来检查必须为正确的参数

如果要去除所有的

#define NDEBUG//必须在包含头文件之前

环境<stdlib.h>

由编译器定义的一个列表

char *getenv(char const *name);

根据名字返回一个对应的字符串

执行系统命令<stdlib.h>

void system(char const *command);

实际的调用和编译器有关, 可以使用NULL来检测是否存在

排序查找

在数组之中以升序对数据进行排列, 和类型无关,数组元素的长度固定

void qsort(void *base, size_t n_elements, size_t el_size, int (*compare)(void const *, void const *))

base要排列的数组

n_elements元素的数量

el_size每个元素的大小

第四个:函数的比较用的函数,返回一个整数, 大于零, 等于零, 小于零, 分别是第一个参数大于第二个, 等于, 小于

  • 查找已经排序的数列

void *bsearch(void const *key, void const *base, size_t n_elements, size_t el_size, int (*compare)(void const *, void const *))

key要查找的值

函数: 一样的话返回0

返回: 查找的指针

locale

为了让函数语言更加的通用,定义了一组特定的参数,每个国家的各不相同

char *setlocale(int category, char const *locale);

category要修改的部分

, 第二个为NULL的时候,返回一个指向对应的指针,可以在之后用来复原, 不是的时候指定新的locale, 成功的话返回的是新的值的指针

修改
LC_ALL整个local
LC_COLLATE对照序列,影响strcoll,strxfrm函数
LC_CTYPE定义于ctype.h中的函数使用的字符类型分类信息
LC_MONETARY格式化货币使用的字符
LC_NUMERIC格式化非货币使用的字符串, 修改格式化输入输出函数和字符串转换函数所使用的小数点符号
LC_TIMEstrftime函数的行为

货币格式

struct lconv *localeconv(void);

locale作用

  • 字符集增加参数

  • 打印方向

  • 小数点符号

如果改变了字符集,比较字符串

int strcoll(char const *s1, char const *s2);//进行比较,但需要更多计算
int strxfrm(char *s1, char const *s2, size_t);//简化计算,把字符串(参数2)转换,再用上面的函数比较
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值