6.5.2 标准函数库

标准函数库提供了一些数据类型转换以及存储器分配等操作函数。标准函数的原型声明包含在头文件stdlib.h中,标准函数库的函数如表6.7所示。下面介绍常用的一些函数。

6.5.2 标准函数库 - 图1

6.5.2 标准函数库 - 图2

1.字符串转换函数atoi、atol和atof

字符串转换函数atoi、atol和atof的函数原型如下。


float atoi(char*sl);

float atol(char*sl);

float atof(char*sl);


这些字符串转换函数用于将字符串转换成特定的数值类型,下面分别进行介绍。

❑函数atoi用于将字符串sl转换成整型数值。输入字符串sl的格式为:[whitespace][{+/-}]数字。其中,whitespace可由空格、/、制表符组成,数字可以是一个或多个十进制数。

❑函数atol用于将字符串sl转换成长整型数值。输入字符串sl中必须包含与规定长整型数值相符的数。输入字符串的格式为:[whitespace][{+/-}]数字。其中,whitespace可由空格、/、制表符组成,数字可以是一个或多个十进制数。当该函数遇到第一个不能构成数字的字符时,将立刻停止对输入字符的读取。

❑函数atof用于将字符串sl转换成浮点数值。输入字符串sl中必须包含与浮点值规定相符的数。输入字符串的格式为:[{+/-}]数字[.数字][{e/E}[{+/-}]数字]。当该函数遇到第一个不能构成数字的字符时,将立刻停止对输入字符的读取。

字符串转换函数atoi、atol和atof的程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

char str1[]=“1212”;//声明并初始化变量

char str2[]=“987654321”;

char str3[]=“37.14”;

int i;//声明变量

long l;

float f;

//初始化串口

i=atoi(str1);//调用atoi函数

printf(“atoi(%s)=%d\n”,str1,i);//输出结果

l=atol(str2);//调用atol函数

printf(“atol(%s)=%ld\n”,str2,l);//输出结果

f=atof(str3);//调用atof函数

printf(“atof(%s)=%f\n”,str3,f);//输出结果

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


atoi(1212)=1212

atoll(987654321)=987654321

atof(37.14)=37.140000


在该程序中,首先定义并初始化变量,接着分别调用atoi、atol和atof函数进行字符串转换,并使用printf函数输出转换后的结果。

2.带返回指针的字符串转换函数strtod、strtol和strtoul

带返回指针的字符串转换函数strtod、strtol和strtoul的原型如下。


float strtod(const chars,char*ptr);

long strtol(const chars,char*ptr,unsigned char base);

unsigner long strtoul(const chars,char*ptr,unsigned char base);


这些带返回指针的字符串转换函数将字符串转换成特定的数值类型,同时返回未转换部分的指针。下面分别进行介绍。

❑函数strtod将输入字符串s转换成浮点型数据。字符串s的格式为:[{+/-}]数字[.数字][{e/E}[{+/-}]数字]。在进行转换的时候,字符串s前面的空格、/、制表符将被忽略。

❑函数strtol将输入字符串s转换成long型数值。字符串s的格式为:[whitespace][{+/-}]数字。其中,whitespace可由空格、/、制表符组成,在进行转换时将被忽略。

❑函数strtoul将输入字符串s转换成unsigned long型数值,溢出时则返回ULONG_MAX。字符串s的格式为:[whitespace][{+/-}]数字。其中,whitespace可由空格、/、制表符组成,在进行转换时将被忽略。

在使用strtol函数和strtoul函数时,base值用于指定基数,通常具有如下含义。

❑如果base的值为0,则数据可以为十进制、八进制、十六进制格式。

❑如果base的值为2~36,表示制定基数的一个整数,字母a~z或A~Z分别表示数据10~36,只有小于base的字母才有效。此时数据为一个字母或数字的非零序列。

在这几个函数中,指针ptr指向输入字符串s中已经转换部分后面的第一个字符。如果不进行转换,则ptr被设为字符串的值,同时返回0。这里举例讲解这些函数在程序中的应用。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

char str1[]=“27.34 Hello”;//声明并初始化变量

char str2[]=“987654321 Hello”;

char str3[]=“1234ABCD Hello”;

char*ptr;

float f1;

long l;

unsigned long ul;

//初始化串口

f1=strtod(str1,&ptr);//调用函数

printf(“strtod(%s)=%f,%s\n”,str1,f1,ptr);//输出结果

l=strtol(str2,&ptr,10);//调用函数

printf(“strtol(%s)=%ld,%s\n”,str2,l,ptr);//输出结果

ul=strtoul(str3,&ptr,16);//调用函数

printf(“strtoul(%s)=%lx,%s\n”,str3,ul,ptr);//输出结果

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


strtod(27.34 Hello)=27.340000,Hello

strtol(987654321 Hello)=987654321,Hello

strtoul(1234ABCD Hello)=1234abcd,Hello


在该程序中,首先初始化字符串,然后分别调用strtod、strtol和strtoul函数进行字符串转换,并使用printf函数打印输出结果。

3.随机函数rand

随机函数rand的函数原型如下。


int rand();


随机函数rand用于产生伪随机数,函数rand返回一个0~32767之间的伪随机数。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int i;//声明并初始化变量

//初始化串口

for(i=0;i<10;i++)

{

printf(“%d”,rand());//输出随机数

}

printf(“\n”);

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


9637 25590 11647 21795 26141 22977 21459 4675 9635 26793


在该程序中,调用rand函数通过串口0输出10个随机数。

4.随机种子函数srand

随机种子函数srand的函数原型如下。


void srand(int n);


随机种子函数srand用来初始化随机数发生器的随机种子。如果不使用srand函数,则对rand函数的相继调用将产生相同的随机序列。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int i;//声明并初始化变量

//初始化串口

srand(37);//随机种子

for(i=0;i<10;i++)

{

printf(“%d”,rand());//输出随机数

}

printf(“\n”);

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


25555 19180 4659 21952 16351 2606 31611 4983 11567 6907


在该程序中,首先调用srand函数初始化随机种子,然后调用rand函数通过串口输出10个随机数。

5.数组内存分配函数calloc

数组内存分配函数calloc的函数原型如下。


void*calloc(unsigned int n,unsigned int size);


其中,n为数组元素的个数,size为数组中每个元素的大小。数组内存分配函数calloc用于为n个元素的数组分配内存空间。该函数所分配的内存区域用0进行初始化,函数的返回值为已分配的内存单元起始地址,如果分配不成功则返回0。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int*ptr;//指针指向有15个整型元素的数组

//初始化串口

ptr=calloc(15,sizeof(int));//调用calloc函数

if(ptr==NULL)

printf(“Fail allocating array\n”);

else

printf(“New array address is%ptr\n”,(void*)ptr);//输出数组地址

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


New array address is x:0010


在该程序中,首先定义变量,接着调用calloc函数申请15个内存。如果申请成功,则通过串口输出申请到的数组的地址,否则将输出错误信息。

6.释放内存函数free

释放内存函数free的函数原型如下。


void free(void xdata*p);


其中,指针p指向待释放的存储区域。p必须是以前用calloc、malloc或realloc函数分配的存储区域,如果p为NULL,则该函数无效。释放内存函数free用于释放前面已分配的内存空间,经free函数所被释放的存储区域可以参与以后的分配。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int*p;//指针指向有15个整型元素的数组

//初始化串口

p=calloc(15,sizeof(int));//申请内存

if(p!=NULL)

{

printf(“New array address is%p\n”,(void*)p);//输出地址

free(p);//释放内存

printf(“Memory free\n”);

}

else

{

printf(“Fail allocating array\n”);

}

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


New array address is x:0200

Memory free


在该程序中,首先定义变量,接着调用calloc函数申请21个内存。如果申请成功,则通过串口输出数组的地址,并通过free函数释放该内存,否则输出错误信息。

7.初始化内存函数init_mempool

初始化内存函数init_mempool的函数原型如下。


void init_mempool(void xdata*p,unsigned int size);


其中,指针p为存储区首地址,size为存储区大小。初始化内存函数init_mempool可对被函数calloc、malloc、free或realloc管理的内存存储区域进行初始化。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

unsigned char xdata malloc_mempool[0x100];

void main(void)//主函数

{

int i;//声明变量

xdata void*p;

//初始化串口

init_mempool(&malloc_mempool,sizeof(malloc_mempool))//调用init_mempool函数

p=malloc(80);

//调用malloc函数

for(i=0;i<80;i++)//循环赋值

((char*)p)[i]=i;

free(p);//释放内存

}


该程序可以在KeilµVision3编译环境中执行。在该程序中,调用init_mempool函数初始化内存,并用malloc函数申请内存空间。程序中通过循环赋值对申请的内存进行写操作,最后通过free函数释放申请到的内存空间。

8.内存分配函数malloc

内存分配函数malloc的函数原型如下。


void*malloc(unsigned int size);


其中,size为分配的空间大小,返回值为指向所分配内存的指针。内存分配函数malloc用于在内存中分配指定大小的存储空间,如果返回NULL,则表示没有足够的内存空间可用。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int*p;//指针指向整型元素

//初始化串口

p=malloc(15);//申请内存

if(p==NULL)

printf(“Fail allocating array\n”);

else

printf(“New array address is%p\n”,(void*)p);//输出地址

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


New array address is x:0000


在该程序中,首先调用malloc函数申请15个内存。如果申请成功,则通过串口输出申请到的地址,否则输出错误信息。

9.调整内存大小函数realloc

调整内存大小函数realloc的函数原型如下。


voidrealloc(void xdatap,unsigned int size);


其中,p为该存储区域的起始地址,size为新分配的存储区域大小。调整内存大小函数realloc用于调整先前分配的存储器区域大小,该函数的返回值为新区域所指向的指针。如果函数返回NULL,则表示没有足够的内存空间可用。该函数在使用时,原内存区域的内容被复制到新内存区域中,如果新内存区域较大,则多出的内存区域不作初始化。程序示例如下。


include<stdlib.h>//头文件

include<stdio.h>

include<reg51.h>

void main(void)//主函数

{

int*p;//指针指向整型元素

int*newp;

//初始化串口

p=malloc(15);//申请内存

if(p==NULL)

printf(“Fail allocating array\n”);

else

{

printf(“New array address is%p\n”,(void*)p);//输出地址

newp=realloc(p,20);//重新分配内存

if(newp==NULL)

printf(“Fail allocating array\n”);

else//输出地址

printf(“New array address is%p\n”,(void*)newp);

}

}


该程序可以在KeilµVision3编译环境中执行,运行的结果如下。


New array address is x:0010

New array address is x:0020


在该程序中,首先定义变量,然后调用malloc函数申请15个内存分配。如果申请成功,则通过串口输出地址,接着使用realloc函数重新分配20个内存空间。最后,通过串口输出相关信息。