首页 > 其他分享 >位运算的巧妙使用 -- 字母大小写转换

位运算的巧妙使用 -- 字母大小写转换

时间:2022-11-08 22:00:30浏览次数:64  
标签:return 运算 -- 大写 int 大小写 小写 转换 函数

引言

C 标准库的 ctype.h 头文件提供了一些函数,可用于测试和映射字符,其中有两个函数,int tolower(int c)该函数把大写字母转换为小写字母,int toupper(int c),该函数把小写字母转换为大写字母。那么它们底层的原理是什么呢?能不能用一个方法就实现大写字母转小写,小写字母转大写呢?

字母大小写转换

ASCLL码

我们知道,​​ASCLL码​​使用7位数编码了128个字符,其中字母'a'-'z'是97到122,字母'A'到'Z'是65到90,想要判断一个字符的类型,或者将一个字符的大写转换为对应的小写都要运用这个ASCLL码表。

tolower和toupper的实现

我们参考这里的代码实现:

​www.aospxref.com/android-12.…​​ 如下:

static inline int islower(unsigned ch) { return (ch - 'a') < 26; }
static inline int isupper(unsigned ch) { return (ch - 'A') < 26; }

18 int LLVM_LIBC_ENTRYPOINT(tolower)(int c) {
19 if (internal::isupper(c))
20 return c + 'a' - 'A';
21 return c;
22 }

18 int LLVM_LIBC_ENTRYPOINT(toupper)(int c) {
19 if (internal::islower(c))
20 return c + 'A' - 'a';
21 return c;
22 }

可以看到,上面的逻辑是很朴素的,判断是否是小写,就使用当前值减去'a'的值,判断是否小于26;判断大写的逻辑也相似。

在转换为小写时,先判断是大写才转换,小写直接返回。如果是大写,则需要加上'a'与'A'的差(很明显,这里加了一个正数);转换大写的逻辑类似。

能否使用一个函数来完成这个判断加转换的工作?

首先,我们注意到,'a'与'A'的差值是97-65=32,是一个比较特殊的数2^5;

其次,我们来看看,这两个字符的二进制表示:

字符

int值

二进制表示

'a'

97

0110 0001

'A'

65

0100 0001

'a'-'A'

32

0010 0000

'z'

122

0111 1010

'Z'

90

0101 1010

这里,可以很明显地看出来,中间的32和上下两个值的关系:异或关系

即:97 = 65 ^ 32,同时65 = 97 ^ 32;

这样我们就可以改写一下转变大小写的函数,只是我们的函数将大写转为小写,小写转为大写,总是反过来,如下:

int reverseChar(int c) {
return c ^ (1 << 5);
}

将原来的加减法加判断,转换为了位运算操作。你体会到位运算的奥妙了吗?

实际上,我们要理解,异或运算相当于不进位的加法,这样一想,对ASCLL编码的操作其实都是可以用异或操作来代替加法的

标签:return,运算,--,大写,int,大小写,小写,转换,函数
From: https://blog.51cto.com/u_15830688/5834980

相关文章

  • 什么是wxml;
    wxml是小程序的标签语言,用来构建小程序页面的结构,类似于网页开发中的html; wxml与html区别  1、标签名称不同 html(div\ span \ img \a)wxml (v......
  • Android 网络架构
    Android网络框架androidapp开发中的最著名的几个网络框架。android原生HttpUrlConnection(2.3以上),HttpClient(andriod2.3以下)volley(google推出)适合高频......
  • flower in 11.8
    久违的鲜花。然而并没有怀念的感觉。最近有时候会有一点想吐的感觉。并不强烈。原因未知。Eafoo问我gtm1514是谁。然而我并不认识。换句话说,我根本没敢接近过这位。您们......
  • MySQL
    1.简介MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,属于Oracle旗下产品。数据库是按照数据结构来组织、存储和管理数据的仓库。是一个长期存储在计算机内......
  • 题解 ABC154F【Many Many Paths】
    problem令\(f(i,j)\)表示,在平面直角坐标系中,从\((0,0)\)出发,每次向上或向右走一步,到达\((i,j)\)的方案数,求:\[\sum_{l_1\leqi\leqr_1}\sum_{l_2\leqj\leqr_2}f(......
  • session实现servlet数据共享
    为了满足老师考试要求,要实现数据共享,要实现顾客登录的功能,登录后进行增删改查要对该顾客进行操作,所以需要将该顾客的一些信息共享给其他操作,找了一些资料,来通过session实现......
  • 实验3
    1.#include<stdio.h>longfun(longs);intmain(){longs,t;printf("enteranumber:");while(scanf_s("%ld",&s)!=EOF){t=fun(s);printf("n......
  • 实验环境安装配置
    ......
  • 如何设置小程序首页
    只需要调整app.json文件页面的路径前后循序即可设置首页;  默认是index是首页,修改首页只需要将作为首页的页面往前提顺序第一即可 ......
  • Java——数据类型转换:自动类型转换&强制类型转换
                             ==================================================================================......