当前位置: 首页 > C, C/C++ > 正文

探秘 C stdlib.h

前言

探秘C标准库系列基本已经快到结尾了,应该还有几篇要写。随着探秘系列的结束,我对C的理解也更多了,就像一句话说的好“C 无所不能,就是我能力还不够” 对于现阶段的计算机体系,C确实无所不能,至少再底层上这样。

__start

stdlib.h 这个库就是一个大杂烩,C标准几乎把乱七八糟的东西都放在这里了,既然本身就没有什么顺序,那么我们也就开始杂谈这个库吧。但是没有规矩不成方圆,我们还是划分出一些结构比较好。

杂谈分组

先分组好了:

整形数学运算组(abs,div,labs,ldiv) 执行简单的整形算术

一些已经封装成库的算法(bsearch,qsort,rand,srand) 一些复杂又使用广范的库。

文本转换(atof,atoi,atol,strtod,strtol,strtoul)  确定文本表示的编码算术值

多字节转换(mblen,mbstowcs,mbtowc,wcstombs 和 wctomb)多字节和宽字节之间的转换

存储分配(calloc,free,malloc 和 realloc) 管理数据对象的堆

环境接口(abort,atexit ,exit,getenv 和system) 程序和执行环境之间的接口

这个库的内容

几个宏与类型:

size_t

wchar_t

div_t    ldiv_t      这两个是函数div ,ldiv 函数的返回类型

typedef struct {

int    quot;     //Quotient        商

int    rem;     //Remainder      余数

}div_t;

typedef struct{

long  int  quot;

long  int  rem;

}ldiv_t;

EXIT_FAILURE   1   EXIT_SUCCESS  0 相信大家都不陌生。就是退出时,环境接口的几个值。

RAND_MAX           2147483647                           是read 函数返回的最大值

MB_CUR_MAX                  展开为整值常量的表达式,其值是当前区域设置指定的扩展字符集中多字节字符的最大字节数目,并且绝不会比MB_LEN_MAX 大。

字符转换函数

atof 函数:

#include<stdlib.h>

double atof ( const  char * nptr);

函数atof 把nptr 指向的字符串初始部分转换成double 类型的表示,出错后的行为等价于:

strtod(nptr ,(char **)NULL);

简单来说就是把 “12.1213”   转换成   数字:12.1213

atoi 函数:

#include<stdlib.h>

int  atoi(const char *nptr);

把字符串转换成整数,出错后等价为(int)strtol (nptr,(char **)NULL,10)

atol  函数:

#includ<stdlib.h>

long  int atol (const char *nptr);

把字符串转换成long  int 型数字,出错后等价strtol(nptr,(char **)NULL,10);

strtod 函数:

#include<stdlib.h>

double strtod(const char *nptr,char ** endptr)

strtod()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,到出现非数字或字符串结束时(‘\0’)才结束转换,并将结果返回。若endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分。如123.456或123e-2.

返回值:

如果存在转换后的值,函数就返回这个double  类型的值。没有执行转换,则返回0.如果正确的转换值在可表示的值范围之外,则返回带正负号的HUGE_VAL  并将宏ERANGE 的值存储在errno 中。

函数strtol

#include<stdlib.h>

long int strtol(const char *nptr,char **endptr,int base);

         参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制等。当base值为0时则是采用10进制做转换,但遇到如’0x’前置字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’的时候会使用8进制做转换。
        一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(‘\0’)结束转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回;若参数endptr为NULL,则会不返回非法字符串。
函数strtoul
       #include<stdlib.h>
      unsigned long int strtoul (const char * nptr,char ** endptr,int base);
      strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制数等。当base值为0时会根据情况选择用哪种进制:如果第一个字符是’0’,就判断第二字符如果是‘x’则用16进制,否则用8进制;第一个字符不是‘0’,则用10进制。一开始strtoul()会扫描参数nptr字符串,跳过前面的空格字符串,直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(”)结束转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的nptr中的字符指针由endptr返回。

伪随机序列产生函数

#include<stdlib.h>

int  rand(void);

函数产生一个随机数,范围在0到RAND_MAX 之间,实现行为不受rand 函数影响。

RAND_MAX 至少应当为32767

 

#include<stdlib.h>

void  srand( unsigned int seed);

设置种子,不然rand 产生的随机数多次运行会是一样的值。最好使用时间来做随机数的种子。

一个小例子:


static   unsigned   long  int next = 1;

int   rand(void){

next = next * 1103515245 + 12345;

return   (unsigned int )(next /65535) % 32768;

}

void  srand(unsigned int  seed){

next = seed;

}

很简单。

内存管理函数

内存管理函数,请参考我之前的博文,内存管理器系列  。 我在这个系列的博文中还是比较清楚的阐述了glibc 库malloc 和 free 的。

环境通信函数

void   abort (void) ;  这个函数之前也说了,看这里

int   atexit(void (*func) (void));

这个函数注册了func 指向的函数,该函数在程序正常终止的时候被调用,而不需要任何参数。

实现应该支持至少32 个函数注册。

 

void   exit (  int  status);

这个函数使程序正常终止。如果执行了多次这个函数。结果未定义。

这个函数首先调用所有的atexit 注册函数,按照他们注册时的反顺序调用。

char *getenv(const char *name);

这个函数搜索宿主提供的环境表。

int  system( const char * string)

函数system 把指针string 指向的串传递给宿主环境,然后命令处理程序按照实现定义的方式执行。

 

查找和排序函数

用 法: void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int(*fcmp)(const void *, const *));
语法:
#include <stdlib.h>
void *bsearch( const void *key, const void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );
参数:第一个:要查找的关键字。第二个:要查找的数组。第三个:指定数组中元素的数目。第四个:每个元素的长度(以字符为单位)。第五个:指向比较函数的指针。
功能: 函数用折半查找法在从数组元素buf[0]到buf[num-1] 匹配参数key。如果函数compare 的第一个参数小于第二个参数,返回负值;如果等于返回零值;如果大于返回正值。数组buf 中的元素应以升序排列。函数bsearch()的返回值是指向匹配项,如果没有发现匹配项,返回NULL
功 能: 使用快速排序例程进行排序
头文件:stdlib.h
用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
参数:
@ 待排序数组首地址
@数组中待排序元素数量
@各元素的占用空间大小
@ 指向函数的指针,用于确定排序的顺序

数学计算函数

      #include<stdlib.h>
      int abs(int j);      long  int labs(long int j);
      计算整数的绝对值,这两个函数类似。
      div_t   div(int number,int denom)
      计算分子除以分母所得的商和余数。
这些函数原理实现可以看我的github   zmr961006  My_lib  https://github.com/zmr961006/My_LIB

本文固定链接: http://zmrlinux.com/2015/12/02/%e6%8e%a2%e7%a7%98-c-stdlib-h/ | Kernel & Me

该日志由 root 于2015年12月02日发表在 C, C/C++ 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 探秘 C stdlib.h | Kernel & Me
【上一篇】
【下一篇】