C语言的实用工具库

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);

前三个函数是旧函数,它们在字符串的开始跳过空格,并把后续字符作为数的一部分,直到第一个不是数的地方停止,把字符串分别转换为doubleintlong 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_SUCCESSEXIT_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;
}

宽字符和多字符处理函数

参考文献

  1. K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值