关于对ctype.h库中函数实现的理解

本来今天是计划要写进制转换的,但是博主又突然发现另一个比较好玩的东西,所以果断决定先来这个;

相信大家或多或少都用过ctype.h (标准c)/ cctype(c++)这个库中的函数:

函数原型: 函数功能: 函数返回
int isalpha(char ch) 检查ch是否是字母   是字母返回非0(在vs2015中为2),否则返回0
int iscntrl(int ch) 检查ch是否 控制字符 是返回非0,否则返回0
int isdigit(char ch) 检查ch是否是数字(0-9) 是返回非0,否则返回0
int isgraph(int ch) 检查ch是否可显示 字符 是返回非0,否则返回0
int islower(int ch) 检查ch是否小写字母(a-z) 是返回非0,否则返回0
int isupper(int ch) 检查ch是否是大写字母(A-Z) 是返回非0,否则返回0

 int tolower(int ch) 将ch字符转换为小写字母             返回与ch相应的小写字母

int toupper(int ch) 将ch 字符 转换成大写字母    返回 与ch相应的大写字母
int isalnum(int ch) 检查ch是否是字母或数字 是字母或数字返回非0,否则返回0
int isprint(int ch) 检查ch是否是可打印 字符 (包括空格)   是返回非0,否则返回0
int  ispunct (int ch) 检查ch是否是标点 字符   是返回非0,否则返回0
int isspace(int ch) 检查ch是否是 空格符/ 跳格符( 控制字符 )/换行符   是返回非0,否则返回0
int  isxdigit (int ch) 检查ch是否是一个16进制数学 字符    是返回非0,否则返回0

int isascii(int ch) 测试参数是否是ASCII码0-127   是返回非0,否则返回0


但是大家在想的时候有没有认真的思考过,这些函数是如何实现的?
先附上这个神奇好玩的代码:
#define  U  0x01  //写字母
#define  L  0x02  //小写字母
#define  D  0x04  //数字
#define  C  0x08  //控制字符
#define  P  0x10  //可打印字符
#define  S  0x20  //空格符/跳格符(控制字符)/换行符 
#define  X  0x40  //16进制基数32
#define  SP 0x80  //空格
extern unsigned char ctype[];
extern char ctmp;
unsigned char ctype[] = {0,         /* EOF */
     C, C, C, C, C, C, C, C,            /* 0-7 */
     C, C| S, C| S, C| S, C| S, C| S, C, C,     /* 8-15 */
     C, C, C, C, C, C, C, C,            /* 16-23 */
     C, C, C, C, C, C, C, C,            /* 24-31 */
     S| SP, P, P, P, P, P, P, P,            /* 32-39 */
     P, P, P, P, P, P, P, P,            /* 40-47 */
     D, D, D, D, D, D, D, D,            /* 48-55 */
     D, D, P, P, P, P, P, P,            /* 56-63 */
     P, U| X, U| X, U| X, U| X, U| X, U| X, U,  /* 64-71 */
    U, U, U, U, U, U, U, U,            /* 72-79 */
     U, U, U, U, U, U, U, U,            /* 80-87 */
     U, U, U, P, P, P, P, P,            /* 88-95 */
     P, L| X, L| X, L| X, L| X, L| X, L| X, L,  /* 96-103 */
     L, L, L, L, L, L, L, L,            /* 104-111 */
     L, L, L, L, L, L, L, L,            /* 112-119 */
     L, L, L, P, P, P, P, C,            /* 120-127 */
  //剩下的都初始化为零;
                         }
int isupper(int c) 
{
  return _ctype[c] & U;
}
int toupper(int c) 
{
  if (_ctype[c] & L) 
    return c - ('a' - 'A');
else 
    return c;

}
字数原因,只在这里贴了两个,其他的都是同一个思想,以此类推就好。
今天看到的这个是通过映射和位运算的方式解释的,他先将整个ASCII表分区(按目标的分类,比如大小写字母,比如数字等每一种类用一个可以代表的值来表示),不同的部分用不同的值表示,然后用了指针在运算时进行直接读取表中数值,避免了传统方式上的遍历检索,根据相应下标映射出当前区域的定义好的值,与目标区域的值进行位运算,然后返回结果。

其实博主在看到这个神奇的东西之前觉得里面的函数功能是应该可能是这样实现的(以其中判断字符是否大写和转换大小写为例):
int isupper(int ch)
{
    if (ch >=65 && ch <= 90)
        return 1;
    else 
        return 0;
}
char toupper(int ch)
{
    if (ch >=97 && ch <= 122)
        return (ch - 32);
    else 
        return ch;
}
不知道都多少人跟我之前的想法一样 哈哈.....



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值