C语言在<stdlib.h>
中声明了7类不同的实用工具函数,包括字符串转换函数、伪随机序列生成函数、内存管理函数、与外部环境通信的函数、搜索和排序函数、整数算术运算函数以及多字节字符和字符串函数。
字符串转换函数
字符串转换函数的作用是将含有字符格式的字符串转换成它的实际数值。一共包括以下六个函数:
double atof(const char *nptr);
int atoi(const char *nptr);
long int atol(const char *nptr);
double strtod(const char *nptr, char **endptr);
long int strtol(const char *nptr, char **endptr, int base);
unsigned long int strtoul(const char *nptr, char **endptr, int base);
前三个函数是旧函数,它们在字符串的开始跳过空格,并把后续字符作为数的一部分,直到第一个不是数的地方停止,把字符串分别转换为double
,int
和long in
类型的值。
下面三个是新函数,它们会通过修改endptr
指向的变量来指出转换停止的位置,还可以通过base
指定转换的基数,还更善于处于错误,当转换产生的值过大时, 会将ERANGE
放在<errno.h>
的errno
变量中。
/*************************************
* string_transfer.c *
* *
* C语言使用工具库中的字符串转换函数 *
* 案例摘自C语言程序设计-现代方法一书*
*************************************/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK_VALID printf(" %s %s\n", \
errno != ERANGE ? "Yes" : "No", \
(*ptr) == '\0' ? "Yes" : "No");
int main(int argc, char *argv[])
{
char *ptr;
if (argc != 2)
{
printf("usage: no converted string\n");
exit(EXIT_FAILURE);
}
printf("Function Return Value\n");
printf("-------- ---------------\n");
printf("atof %g\n", atof(argv[1]));
printf("atoi %d\n", atoi(argv[1]));
printf("atol %ld\n", atol(argv[1]));
printf("Function Return Value Valid? String consumed?\n"
"-------- ------------ ------- ----------------\n");
errno = 0;
printf("strtod %-12g", strtod(argv[1], &ptr));
CHECK_VALID;
errno = 0;
printf("strtol %-12ld", strtol(argv[1], &ptr, 10));
CHECK_VALID;
errno = 0;
printf("strtoul %-12lu", strtoul(argv[1], &ptr, 10));
CHECK_VALID;
return 0;
}
伪随机数序列生成函数
伪随机数序列生成函数用以生成伪随机数,包括以下两个函数:
int rand(void);
void srand(unsigned int seed);
rand
函数每次返回一个由随机数种子产生的0到RAND_MAX之间的一个数。srand
提供用于rand的随机数种子。使种子值随机化的方法就是利用<time.h>
中的time
函数根据当前日期和时间生成一个数。
/*************************************
* using_rand.c *
* *
* C语言使用工具库中的随机数生成函数 *
* 案例摘自C语言程序设计-现代方法一书*
*************************************/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, seed;
printf("This program displays the first ten values of rand.\n");
for (;;)
{
for (i = 0; i < 10; i++)
printf("%d ", rand());
printf("\n\n");
printf("Enter new seed value(0 to terminate): ");
scanf("%d", &seed);
if (seed == 0)
break;
srand(seed);
}
return 0;
}
内存管理函数
内存管理函数用于内存的分配和释放,包括以下几个函数:
void *malloc(size_t size);
void *calloc(size_t n, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
malloc
函数分配内存块,但不对内存块进行初始化,calloc
函数分配内存块,并对内存块清零,realloc
调整已分配内存块的大小。free
函数用以释放不再使用的内存块。
/****************************************
* memory_alloc.c *
* *
* C语言工具库中的内存管理函数 *
***************************************/
#include <stdio.h>
#include <stdlib.h>
#define N 10
int main()
{
int *nums = malloc(N * sizeof(int));
int i;
for (i = 0; i < N; i++)
printf("%d ", nums[i]);
printf("\n");
int *nums2 = calloc(N, sizeof(int));
for (i = 0; i < N; i++)
printf("%d ", nums2[i]);
printf("\n");
int *nums3 = realloc(nums2, N + 10);
for (i = 0; i < N + 10; i++)
printf("%d ", nums3[i]);
printf("\n");
free(nums);
free(nums3);
return 0;
}
与环境通信函数
与环境通信函数支持程序正常或不正常终止,并为操作系统返回一个状态码;从用户的外部环境获得信息;执行操作系统的命令,包括以下几个函数:
void exit(int n);
void abort(void n);
int atexit(void (*func)(void));
char *getenv(const char *name);
int system(const char *command);
在函数的任何地方执行exit(n)
等价于在main
函数中执行return n
,在<stdlib.h>
提供了作为exit
的参数的两个宏EXIT_SUCCESS
和EXIT_FAILURE
。
通过atexit
函数向程序注册函数func
,那么当终止程序时,atexit
函数会执行该函数,如果注册了多个函数,将首先调用最后注册的函数。
abort
函数导致程序异常终止,不会调用atexit
注册的函数。
getenv
函数可以获取用户的环境变量的字符串。system
函数允许C语言执行另一个程序,参数为命令行。system
的返回值由实现定义,通常返回来自程序的终止码,已测试这个函数是否正常结束。
/**************************************
* env_inter.c *
* *
* C语言工具库的外部环境交互函数 *
**************************************/
#include <stdio.h>
#include <stdlib.h>
void func()
{
printf("程序结束前调用函数1\n");
}
void func2()
{
printf("程序结束前调用函数2\n");
}
int main()
{
int sel;
scanf("%d", &sel);
atexit(func);
atexit(func2);
switch(sel)
{
case -1:
printf("异常终止\n");
abort();
case 0:
printf("正常退出\n");
exit(EXIT_SUCCESS);
case 1:
{
char *path = getenv("PATH");
printf("PATH为%s\n", path);
break;
}
case 2:
system("ls -la");
break;
default:
break;
}
return 0;
}
搜索和排序函数
搜索和排序函数有以下两类:
void *bsearch(const void *key, const void *base, size_t num, size_t size, int (*compar)(const void*, const void*));
void qsort(void *base, size_t num, size_t size, int (*compar)(const void*, const void*));
bsearch
采用二分查找方法在有序的数组中搜索关键词。key
指向关键字,base
指向数组,num
是数组中元素数量,size
是每个数组元素的大小,compare
是指向比较函数的指针。比较函数根据两个元素是大小,小于还是等于,返回正整数,负整数和0.
qsort
函数采用对数组进行排序,其中base
指向数组,num
为数组中元素数量,size
为每个数组元素大小,compar
为指向比较函数的指针。
/*************************************
* search_sort_method.c *
* *
* C语言工具库中的搜索和排序函数 *
*************************************/
#include <stdio.h>
#include <stdlib.h>
#define N 10
int comp(const void* x, const void *y)
{
int *ix = (int *)x;
int *iy = (int *)y;
if (*ix > *iy)
return 1;
else if (*ix == *iy)
return 0;
else
return -1;
}
int main()
{
int *nums = malloc(N * sizeof(int));
printf("请任意输入%d个整数: ", N);
int i;
for (i = 0; i < N; i++)
scanf("%d", nums + i);
qsort(nums, N, sizeof(int), comp);
printf("排序后:");
for (i = 0; i < N; i++)
printf("%d ", nums[i]);
printf("\n");
int k = 40;
int *findedItem = bsearch(&k, nums, N, sizeof(int), comp);
if (findedItem != NULL)
printf("%d在数组中\n", *findedItem);
else
printf("%d不在数组中\n", k);
return 0;
}
整数算术运算函数
整数算术运算函数包括以下几个:
int abs(int j);
div_t div(int number, int denom);
long int labs(long int j);
ldivt ldiv(long int num, long int denom)
abs
返回int
型变量的绝对值,labs
返回long
型变量的绝对值,div
用第二个参数去除第一个参数,返回div_t
型值,包含商成员(quot
)和余数成员(rem
)的结构。 ldiv
是处理长整型之间的除法的函数,也返回一个ldiv_t
型的结构变量。
/**************************************
* int_calc.c *
* *
* 整数算术运算函数库 *
**************************************/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x = -10;
printf("%d的绝对值为%d\n", x, abs(x));
long y = -5000L;
printf("%ld的绝对值为%ld\n", y, labs(y));
int x1 = 500;
int x2 = 23;
div_t dit = div(x1, x2);
printf("%d除以%d = %d余%d\n", x1, x2, dit.quot, dit.rem);
long y1 = 5000L;
long y2 = 13L;
ldiv_t ldit = ldiv(y1, y2);
printf("%ld除以%ld = %ld余%ld\n", y1, y2, ldit.quot, ldit.rem);
return 0;
}
多字节和字符串处理函数
stdlib.h包含处理宽字符和多字节字符的函数,分别为:
int mblen(const char *s, size_t n);
int mbtowc(wchar_t *pwc, const char *s, size_t n);
int wctomb(char *s, wchar_t wchar);
size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
size_t wcstombs(char *s, const wchar_t *s, size_t n);
mblen
检测第一个参数指向的字节数组是否是一个有效的多字节字符序列。mbtowc
将多字节字符转换为单字符,wctomb
将宽字符转换为多字节字符。mbstowcs
将多字节字符转换为宽字符,wcstombs
将宽字符串转换为多字节字符串。
/**************************************
* using_mb_wc_func.c *
* *
* C语言工具库中的宽字符和多字节字符 *
* 处理函数 *
**************************************/
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
int main()
{
setlocale(LC_ALL, "");
wchar_t zhong = L'中';
char mb[MB_CUR_MAX];
int num = wctomb(mb, zhong);
wprintf(L"mb的字节数为%d\n", num);
if (mblen(mb, MB_CUR_MAX))
wprintf(L"mb是一个有效的多字符序列!\n");
wchar_t china[] = L"中国";
char *mb2 = malloc(MB_CUR_MAX * sizeof(china)/sizeof(wchar_t));
size_t num2 = wcstombs(mb2, china, MB_CUR_MAX * sizeof(china)/sizeof(wchar_t));
wprintf(L"mb2的字节数为%d\n", num2);
wchar_t love[3] = L"";
mbstowcs(love, mb2, 2);
wprintf(L"我爱%Ls\n", love);
return 0;
}
参考文献
- K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社