第十四章 标准函数库
算术<stdlib.h>
int abs(int value); //求绝对值
long int labs(long int value); //对长整型求绝对值
div_t div(int denominator, int numerator);
第1个参数(分母)除以第2个参数(分子),产生商与余数。返回的结果是一个定义的结构体
typedef struct {
int quot/*商*/, rem/*余数*/;
} div_t;
quot = numerator/denominator
rem = numerator%denominator
ldiv_t ldiv(long int denominator, long int numerator);
typedef struct {
long quot, rem;
} ldiv_t;
与div功能一样,适用于长整型。
这两个除法函数中,当denominator为0或者当商或余数无法用返回类型表示时,这些函数的行为是未定义的(不同的编译器不同,不一定导致定义域错误)
随机数<stdlib.h>
int rand(void);
返回一个范围在0到RAND_MAX(至少为32768)之间的随机数,为了得到一个更小范围的随机数,产先把这个函数的返回值根据所需范围的大小进行取模,然后通过加上或减去一个偏移量对它进行调整。
void srand(unsigned int seed);
为了避免程序每次运行时获得相同的随机数,可以调用srand初始化随机数生成器。种子一般使用时间:srand((unsigned int)tim(0))
如果种子相同,则每次(不是指同一运行过程中多次调用,而是指定程序运行结束后再次运行)程序运行产生的随机数序列是一样的。如果未使用srand就调用了rand,则默认会使用srand(1)先作初始化操作。
字符串转换整数<stdlib.h>
字符串转换函数将字符串转换成数值。这些函数的第一个参数如果包含了前导空白字符,它们都将被忽略,然后函数把合法字符转换为指定类型的值。如果存在任何非法缀尾字符,它们也将被忽略。
int atoi(char const *string);
long int atol(char const *string);
上面两个函数将以10为基数进行转换,下面两个可以指定基数。
long int strtol(char const *string, char **unused, int base);
unsigned long int strtoul(char const *string, char **unused, int base);
unused参数是一个二级指针,它指向了第一个未被转换的字符指针,也以为NULL,如果为NULL则不会存储未被成功转换的缀尾非法串。
如果基数base为0,则数值的格式可以是十进制常量、八进制常量或十六进制常量,具体是什么是根据它的格式推断出来的。除基数可以为0外,还可以是2到36(包含两者),字母a~z(A~Z)分别表示10~35的数字。一种特殊情况,如果基数为16,则数值可以以0x或0X开始(在符号位之后),这个前缀将被忽略。
如果这些函数的string参数并不是一个合法的数值串,函数就返回0。如果被转换的值无法表示,则会设置errno为ERANGE值,并返回以下值:
strtol:如果值太大且为负数,返回LONG_MIN,如果太大且为正数,返回LONG_MAX
strtoul:如果值太大,返回ULONG_MAX
浮点型函数
头文件math.h包含了函数库stdlib.h中剩余的数学函数的声明,这些函数返回值以及绝大多数都是double类型。
如果一个函数的参数不在函数定义域之内,称为定义域错误(domain error),例如:
sqrt(-5.0);
perror("sqrt");//sqrt: Domain error
当出现一个定义域错误时,函数返回一个由编译器定义的错误值,并且在errno中存储EDOM这个值。
如果一个函数的结果值过大或过小,无法用double类型表示,这称为范围错误(range error),例如:
printf("%f ",exp(LONG_LONG_MAX));//1.#INF00
perror("exp");//exp: Result too large
由于结果值太大,函数返回 HUGE_VAL,它是一个在math.h中定义的double类型值。如果一个函数的结果值太小,无法用一个double表示,函数将返回0,这种情况也属于范围错误,但errno会不会设置为ERANGE取决于编译器;
对数和指数函数<math.h>
double exp(double x);
返回e值的x次幂,也就是ex
double log(double x);
返回x以e为底的对数,即自然对数。logex
double log10(double x);
返回x以10为底的对数。log10x
如果它们的参数为负,两个对数函数都将出现定义域错误。
x以任意一个b为底的对数可以通过下面的公式进行计算:
logbx = logex/logeb
log39 = loge9/loge3 = log(9)/log(3) = 2
printf("%f ", log(9)/log(3));//2.000000
幂<math.h>
double pow(double x, double y);
返回xy
double sqrt(double x);
底数、顶数、绝对值、余数<math.h>
double floor(double x);
返回不大于其参数的最大整数值,这个值以double的形式返回,是因为double能够表示的范围远大于int。
double ceil(double x);
返回不小于其参数的最小整数值。
double fabs(double x);
返回绝对值
double fmod(double x, double y);
返回x除以y所产生的余数,由于操作符 % 只能用在两个整数之间,所以提供了这个函数
字符串转换浮点数<math.h>
这些函数和整数字符串转换函数类似,只不守它们返回浮点值
double atof(char const *string);
double strtod(char const *string, char **unused);
日期和时间函数
处理器时间<time.h>
clock_t clock(void);
返回从程序开始执行起处理器所消耗的时间,这个值可能是个近似值。如果需要更精确的值,你可以在main函数刚开始执行时调用clock,然后把以后调用clock时所返回的值减去前面的那个值。如果无法提供处理器时间,或太大无法用clock_t表示,则返回-1。
clock函数返回一个数字,它是由编译器定义的,通常它是处理器时钟滴答的次数,为了把这个值转换为秒,你应该把它除以常量 CLOCKS_PER_SEC
typedef long clock_t;
#define CLOCKS_PER_SEC ((clock_t)1000)
当天时间<time.h>
time_t time(time_t *returned_vale);
如果参数是一个非NULL的指针,时间值也将通过这个指针进行存储。如果机器无法提供当前日期与时间,或时间值太大,无法用time_t表示,则返回-1。正常一般返回的是从1970.1.1 00:00:00开始到今天的秒数(注,不像Java中返回的是毫秒数,如果time_t是一个long型,且结果是以秒为单位的,这个值会在2038年溢出)。注:标准并未规定函数的返回结果用秒来表示,不过从大多数的实现来看是秒。
typedef __time32_t time_t;
typedef __int32 __time32_t;
#define __int32 long
日期和时间转换<time.h>
char *ctime(time_t const *time_value);
返回的格式固定为:Fri Apr 08 17:52:04 2011