库函数
标准C库函数
名称 | 函数类型 |
---|---|
<assert.h> | 诊断函数 |
<ctype.h> | 字符测试 |
<errno.h> | 错误检测 |
<float.h> | 系统定义的浮点型界限 |
<limits.h> | 系统定义的整数界限 |
<locale.h> | 区域定义 |
<math.h> | 数学 |
<stjump.h> | 非局部的函数调用 |
<signal.h> | 异常处理和终端信号 |
<stdarg.h> | 可变长度参数处理 |
<stddef.h> | 系统常量 |
<stdio.h> | 输入输出 |
<stdlib.h> | 多种公用函数 |
<string.h> | 字符串处理 |
<time.h> | 时间和日期函数 |
数学函数
绝对值函数
原型 | 功能 |
---|---|
int abs(int n) | 计算整数n的绝对值 |
long labs(long n) | 计算长整数n的绝对值 |
double fabs(double x) | 计算双精度实数x的绝对值 |
示例代码:求整数的绝对值
#include <stdio.h> //包含标准输入输出头文件
#include <math.h> //包含数学头文件
int main()
{
int x;
x=-5;
printf("|%d|=%d\n",x,abs(x)); //调用绝对值函数
x=0;
printf("|%d|=%d\n",x,abs(x)); //调用绝对值函数
x=+5;
printf("|%d|=%d\n",x,abs(x)); //调用绝对值函数
getchar(); //等待键入字符
return 0;
}
幂函数和开平方函数
原型 | 功能 |
---|---|
double pow(double x,double y) | 计算双精度实数x的y次幂 |
double sqrt(double x) | 计算双精度实数x的平方根 |
指数函数和对数函数
原型 | 功能 |
---|---|
double exp(double x) | 计算e的双精度实数x次幂 |
double log(double x) | 计算以e为底的双精度实数x的对数ln(x) |
double log10(double x) | 计算以10为底的双精度实数x的对数log10(x) |
三角函数
原型 | 功能 |
---|---|
double sin(double x) | 计算双精度实数x的正弦值 |
double cos(double x) | 计算双精度实数x的余弦值 |
double tan(double x) | 计算双精度实数x的正切值 |
double asin(double x) | 计算双精度实数x的反正弦值 |
double acos(double x) | 计算双精度实数x的反余弦值 |
double atan(double x) | 计算双精度实数x的反正切值 |
double sinh(double x) | 计算双精度实数x的双曲正弦值 |
double cosh(double x) | 计算双精度实数x的双曲余弦值 |
double tanh(double x) | 计算双精度实数x的双曲正切值 |
取整函数和取余函数
原型 | 功能 |
---|---|
double ceil(double x) | 计算不小于双精度实数x的最小整数 |
double floor(doulbe x) | 计算不大于双精度实数x的最大整数 |
double fmod(double x,double y) | 计算双精度实数x/y的余数,余数使用x的符号 |
double modf(double x,double *ip) | 计算x的小数部分,使用x的符号,x的整数部分,使用x的符号,都被双精度实数ip指向x的y次幂 |
示例代码:取整和取余函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <math.h> //包含数学头文件
int main()
{
double x,y,i;
x=74.12;
y=6.4;
printf("74.12/6.4: %f\n",fmod(x,y)); //调用取余函数
x=74.12;
y=-6.4;
printf("74.12/(-6.4): %f\n",fmod(x,y)); //调用取余函数
x=modf(-74.12,&i);
printf("-74.12=%.0f+(%.2f)",i,x);
getchar(); //等待键入字符
return 0;
}
字符串处理函数
C语言没有为以数组为整体的对象提供内置操作,例如数组赋值或者数组比较。因为字符串只是一个以’\0’字符终止的字符数组,不是一个有它自己的权限的数据类型,这就意味着不能为字符串提供赋值运算和关系运算。
但是,在C语言的标准库函数中,包含了大量的字符串处理函数和字符处理函数,起到辅助完成字符串进行处理的功能。
字符串库函数的调用方式与所用的C语言函数的调用方式一样,要使用这些字符串函数,需要包含头文件<string.h>。
字符串长度函数
原型 | 功能 |
---|---|
int strlen(char *d) | 返回字符串d的长度,不包括终止符NULL |
字符串连接函数
原型 | 功能 |
---|---|
char strcat(char d,char *s) | 连接字符串s到字符串d,返回字符串d |
char strncat(char d,char *s,int n) | 连接字符串s中至多n个字符到字符串d,返回字符串d |
字符串连接函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <string.h> //包含字符串处理头文件
int main()
{
char d1[20]="Hello";
char d2[20]="Hello";
char *s1=" World";
char *s2=" Worldabc"
strcat(d1,s1); //调用字符串连接函数
printf("%s\n",d1);
strncat(d2,s2,6); //调用字符串连接函数
printf("%s\n",d2);
getchar(); //等待键入字符
return 0;
}
字符串复制函数
原型 | 功能 |
---|---|
char strcpy(char d,char *s) | 复制字符串s到字符串d,返回字符串d |
char strncpy(char d,char *s,int n) | 复制字符串s中至多n个字符到字符串d;如果s小于n个字符,用’\0’补上,返回字符串d |
void memcpy(void d,void *s,int n) | 从s复制n个字符到d,返回字符串d |
void memmove (void d,void *s,int n) | 和memcpy相同,即使d和s部分相同也运行 |
字符串复制函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include < string.h > //包含字符串处理头文件
int main()
{
char *s1="Hello World";
char *s2="Hello World";
char d1[20]="***************";
char d2[20]="***************";
strcpy(d1,s1); //调用字符串复制函数
printf("%s\n",d1);
strncpy(d2,s2,strlen(s2)); //调用字符串复制函数
printf("%s\n",d2);
getchar(); //等待键入字符
return 0;
}
字符类型判断函数
原型 | 功能 |
---|---|
int isalnum(int c) | 如果整数c是文字或数字返回非零,否返回零 |
int isalpha(int c) | 如果整数c是一个字母返回非零,否返回零 |
int iscntrl(int c) | 如果整数c是一个控制符返回非零,否返回零 |
int isdigit(int c) | 如果整数c是一个数字返回非零,否返回零 |
int isgraph(int c) | 如果整数c是可打印的(排除空格)返回非零,否返回零 |
int islower(int c) | 如果整数c是小写字母返回非零,否返回零 |
int isprint(int c) | 如果整数c是可打印的(包括空格)返回非零,否返回零 |
int ispunct(int c) | 如果整数c是可打印的(除了空格、字母或数字之外)返回非零,否返回零 |
int isspace(int c) | 如果整数c是一个空格返回非零,否返回零 |
int isupper(int c) | 如果整数c是大小字母返回非零,否返回零 |
int isxdigit(int c) | 如果整数c是十六进制数字返回非零,否返回零 |
转换和存储管理函数
转换函数
原型 | 功能 |
---|---|
int atoi(string) | 转换一个ASCII字符串为一个整数。在第一个非整型字符处停止 |
double atof(string) | 转换一个ASCII字符串为一个双精度数。在第一个不能被解释为一个双精度数的字符处停止 |
string itoa(int,char *,int) | 转换一个整数为一个ASCII字符串。为返回的字符串分配的空间必需足够大于被转换的数值 |
转换函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <stdlib.h> //包含转换和存储头文件
int main()
{
int num=12345;
char *str="12345.67";
char array[10];
itoa(num,array,sizeof(array)); //调用转换函数
printf("num=%d,array=%s\n",num,array);
printf("%d",atoi(str));
getchar(); //等待键入字符
return 0;
}
存储管理函数
原型 | 功能 |
---|---|
void *malloc(size_tn) | 为一个大小为n的对象分配存储空间 |
void *calloc(size_n,size_n) | 为n个对象的数组分配存储空间,每个大小为n,初始化所有被分配的自己为0 |
void realloc(void p,size_n) | 重新分配空间的大小为n,内容保持与旧的相同,等于新的大小 |
void free(void *p) | 释放指向的空间 |
例如,函数调用malloc(10*sizeof(char))请求足够存储10个字符存储空间,而函数malloc(sizeof(int))请求足够存储一个整型数据的存储空间。
被malloc()分配的空间来自计算机空闲存储区,这个存储区形成在堆上。堆是由未分配的存储区组成的,这个存储区能够在这个程序执行时根据请求分配给一个程序。程序中如果使用了free()函数,可以把使用malloc()分配的存储区被返回给这个堆。
为了提供访问这些位置的能力,malloc()返回已经被保存的第一个位置的。当然,这个地址必须赋值给一个指针。通过malloc()返回一个指针,对创建数组或者个是一组数据结果是很有帮助的。需要注意到,返回的指针类型是void类型,这样不管请求的数据是什么类型,返回的地址必须使用强制类型转换重新转换成希望得到的类型。
例如,有个变量pt,是一个指向整型的指针,已经使用malloc()创建了,如下所示:
pt = malloc(sizeof(int));
malloc创建的是void指针类型,所以需要重新定义pt为一个整型指针,如下所示:
(int *)pt;
下面看一段代码,功能是创建一个整型数组,数组大小由用户在运行时输入决定。
int *pt;
printf(“输入数值\n”);
scanf(“%d”,&number);
pt = (int *) malloc(number * sizeof(int));
经过这样的处理,就可以使用pt[i]或者*(pt+i)访问数组中第i个元素了。
随机函数
- rand()
- srand()
初识随机函数
在实践中,找到真正的随机数字是很困难的。数字计算机只能在一个限定的范围内和有限的精度下去处理数字。在大多数情况下,一个人能够做的最好的方法是产生伪随机数,而不是真正意义的随机数,它的意义是,单次产生的数列是无法预测的,但是每次都会生成同样一组随机数列。
标准C函数库提供一个随机数函数,rand()函数,它返回[0,MAX]之间均匀分布的伪随机整数。rand()函数不接受参数,默认以1为种子(即起始值),它总是以相同的种子开始,所以形成的伪随机数列也相同,不是真正的随机。这是有意设计的,目的是为了便于程序的调试。
另一个函数srand(),可以使用该函数指定不同的数(无符号整数)为种子。但是如果种子相同,伪随机数列也相同。有两种方法可以采用,一种办法是让用户输入种子,但是效果不是很理想;另外一种比较理想的方法是采用变化的数,常用时间来作为随机数生成器的种子。这样种子不同,产生的随机数也也就不同。
使用随机函数
rand()函数没有参数,它返回一个从0到最大值之间的随机整。如果要产生0~10的随机整数,可以表达为:
int n= rand() % 11;
如果要产生1~10,则是这样:
int n= 1 + rand() % 10;
总的来说,要生成一个[a,b]范围内的一个随机整数,可以用下式来表示:
int n=a + rand() % (b-a+1);
随机函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <stdlib.h> //包含转换和存储头文件
#include <time.h> //包含日期时间处理头文件
#define MAX 100
int main()
{
int i;
srand( (unsigned)time( NULL ) ); //随机数播种函数
for (i=0;i<10;i++) //产生十个随机数
printf("%d\n",rand()%MAX); //设定随机数范围并输出
return 0;
}
srand()函数的参数是一个带NULL参数的time()函数。NULL参数使time()函数以秒为单位读取计算机内部时钟的时间。然后srand()函数使用使这个时间初始化rand()随机函数发生函数,也就是常说的产生一个以当前时间开始的随机种子。
在实践中,需要对rand()函数生成的随机数进行修改,比如需要生成的随机数的范围在0到1之间,那该怎么办呢?
可以这样做,首先产生范围0~10的随机正整数,然后除以10.0,根据需要再明确精度,这样就可以了,其它情况依此类推。
日期和时间处理函数
char *asctime(const struct tm *timeptr);
将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。
char *ctime(const time_t *timep)
将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。
struct tmgmtime(const time_ttimep)
参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。
struct tm *localtime(const time_t *timep)
参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回. 结构tm的定义请参考gmtime()。
例如下面的代码:
struct tm
{
int tm_sec; /*目前秒数,正常范围为0-59,但允许至61秒*/
int tm_min; /*目前分数,范围0-59*/
int tm_hour; /*从午夜算起的时数,范围为0-23*/
int tm_mday; /*目前月份的日数,范围01-31*/
int tm_mon; /*目前月份,从一月算起,范围从0-11*/
int tm_year; /*从1900 年算起至今的年数 */
int tm_wday; /*一星期的日数,从星期一算起,范围为0-6*/
int tm_yday; /*从今年1月1日算起至今的天数,范围为0-365*/
};
此函数返回的时间日期未经时区转换,而是UTC时间(UTC是协调世界时 Universal Time Coordinated的英文缩写),是由国际无线电咨询委员会规定和推荐,并由国际时间局负责保持的以秒为基础的时间标度。UTC相当于本初子午线(即经度0°)上的平均太阳时,过去曾用格林威治平均时(GMT)来表示。
日期和时间函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <time.h> //包含日期时间处理头文件
int main()
{
time_t startTime = clock();
char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep;
struct tm *p;
time(&timep);
printf("%s",ctime(&timep)); //调用日期时间处理处理函数
p=gmtime(&timep); //调用日期时间处理处理函数
printf("%s",asctime(p)); //调用日期时间处理处理函数
printf("%d-%d-%d ",(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);
printf("%s %d:%d:%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
p=localtime(&timep); //调用日期时间处理处理函数
printf ("%d-%d-%d ", (1900+p->tm_year),( 1+p->tm_mon), p->tm_mday);
printf("%s %d:%d:%d\n", wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec);
time_t endTime = clock();
//double(endTime-startTime)/CLOCKS_PER_SEC;
return 0;
}
诊断函数
Øassert()函数是诊断函数,它的作用是测试一个表达式的值是否为false,也就是为0,并且在条件为false时终止程序,参数的表达式的结果是一个整型数据。assert()函数定义在标准函数库<assert.h>头文件中定义的。
例如:assert(a==b);
Ø当a和b想当时,表达的结果是1,也就等同于true,如果a和b不等时,结果就是0,也就是false,然后根据结果决定是否终止程序。当程序出现异常时,可以使用abort()函数以非正常方式立即结束应用程序。
诊断函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <assert.h> //包含诊断处理头文件
struct ITEM
{
int key;
int value;
};
//诊断ITEM结构对象是否为false
void additem(struct ITEM *itemptr)
{
assert(itemptr != NULL); //调用诊断函数
}
int main()
{
additem(NULL);
return 0;
}
exit()函数
exit()函数表示结束程序,它的返回值将被忽略。如果要是exit()函数,需要包含<stdlib.h>头文件。
函数原型如下:void exit(int retval);
exit函数的应用
#include <stdio.h> //包含标准输入输出头文件
#include <stdlib.h> //包含转换和存储头文件
int main()
{
int i;
for(i=0;i<10;i++)
{
if(i==5) exit(0);
else
{
printf("%d",i);
getchar(); //等待键入字符
}
}
getchar(); //等待键入字符
return 0;
}
qsort()函数
qsort()函数包含在<stdlib.h>头文件中,此函数根据你给的比较条件进行快速排序,通过指针移动实现排序。排序之后的结果仍然放在原数组中。使用qsort函数必须自己写一个比较函数。
函数原型:
void qsort ( void * base,int n, int size, int ( * fcmp ) ( const void *, const void * ) )