<stdlib.h>
算数:
1、函数abs和labs返回参数的绝对值
int abs( int value );
long int labs( long int value );
2、函数div和ldiv做除法运算
div_t div( int numerator, int denominator );
ldiv_t ldiv( long int numer, long int denom );
函数第一个参数为分子,第二个参数为分母。产生的结果用 div_t / ldiv_t 结构返回。结构包含的字段为:
int quot; //商
int rem; //余数
随机数:
函数产生的随机数其实通过一定的计算产生的“伪随机数”。
int rand( void );
void srand( unsigned int seed );
排序和查找:
qsort函数以升序的方式对数组中的数据进行排序(快速排序)。qsort是与类型无关的,可以对任意类型的数据进行排序。
void qsort( void *base, size_t n_elements, size_t el_size,
int (*compare)(void const *, void const * ));
第一个参数指向待排序的数组,第二个参数指定数组中元素的数目,第三个参数指定单个元素的长度(以字符为单位)。第四个参数是一个函数指针,用于对需要排序的元素类型进行比较。通过传递一个指向合适的比较函数的指针,可以对任意类型值的数组排序。
<math.h>
常用 ANSI C 标准数学函数:
基本的浮点型数学函数接收 double 型参数,返回值也是 double 型。在上述表格中的函数名加上 f 或者 l 就得到了其 float 型和 long double 型标准函数,如sqrtf () 和 sqrtl () 。
<string.h>
函数的作用都是从 s2 指向的位置拷贝 n 字节(是字节数而非元素个数)到 s1 指向的位置,并且返回 s1 的值。区别在于函数 memcpy 使用了 restrict 关键字,这意味着使用 memcpy() 函数的前提是假设拷贝与被拷贝内存之间是没有重叠的。而 memmove 则无需这样的顾虑,memmove的拷贝过程类似于利用一个中间临时缓存区,先把数据拷贝到缓存区,再从缓存区拷贝数据到目的地。
void *memcpy( void * restrict s1, const void * restrict s2, size_t n );
void *memmove( void *s1, const void *s2, size_t n );
s1 和 s2 的参数类型是 void * ,而 void * 类型的指针可以接收任意类型的指针,所以函数 memcpy 和 memmove 可以实现任意类型的数组的拷贝。(函数 strcpy() 和 strncpy() 只能用于处理字符数组。)
函数memcpy() 不知道也不关心数据的类型,更不会做类型转换,它只会做字节拷贝工作。而通过循环(利用循环按下标依次赋值)把一个数组中的值赋给另外一个数组时,在赋值的过程中是会做数据类型转换的。
<stdarg.h>
可变参数
实现一个可接收可变参数的函数的步骤:
1.提供一个使用省略号的函数原型(形参列表中至少有一个形参和一个“…”,且省略号在最后);
2.在函数体中定义一个 va_list 类型的变量;
3.使用 va_start() 宏把该变量初始化为一个参数列表;
4.使用 va_arg() 宏访问参数列表;
5.使用 va_end() 宏完成清理工作。
传给“…”左边第一个的参数用于指明省略号部分参数的个数(如下面的参数“ lim ”):
//实现参数求和,lim 为待求和参数的数目
double sum( int lim, … )
{
va_list ap;//声明一个对象 ap 用于存储参数
double tot = 0;
va_start( ap, lim );//把 ap 初始化为参数列表
for( int i; i < lim; i++ )
{
tot += va_arg( ap; double );//访问参数列表中的每一项
{
va_end( ap );//清理工作,接收的参数是个 va_list 类型的对象
return tot;
}
打印可变参数列表
下面这组函数用于打印可变参数列表,使用前需要包含头文件<stdio.h>和<stdarg.h>
int vprintf( char const *format, va_list arg );
int vfprintf( FILE *stream, char const *format, va_list arg );
int vsprintf( char *buffer, char const *format, va_list arg );
这些函数与它们对应的标准函数基本相同,这是它们使用了一个可变参数列表。在调用这些函数之前,arg参数必须使用 va_start 进行初始化。
<time.h>
处理器时间:
clock函数返回从程序开始执行起,处理器所消耗的时间。
clock_t clock( void );
当天时间:
time函数返回当前的时间和日期。
time_t time( time_t *returned_value );
日期和时间的转换:
char *ctime( time_t const *time_value );
ctime函数的参数是一个指向 time_t 的指针,并返回一个指向字符串的指针。字符串的格式如下:
Sun Jul 4 04:02:48 1976\n\0
<assert.h>
断言
断言就是声明为真。ANSI C实现了一个assert宏,用来调试程序,原型如下:
void assert( int expression );
代码执行时,assert宏对表达式参数进行测试。若值为0(假),则assert宏就向标准错误打印一条诊断信息并终止程序(错误信息包含表达式和源文件的名字以及断言所在的行号);若表达式值为非零(真),则不做任何处理,程序往下执行。
例如:一个函数必须用一个不为NULL的指针参数进行调用,那么可以用assert验证:
assert( value != NULL );
assert只适用于验证必须为真的表达式。程序完整地测试完毕后,不必挨个将源文件中的断言删除,只需在源文件包含头文件<assert.h>之前加上定义 #define NDEBUG 即可使断言不生效。