位运算对字母大小写的转换
先定义一个字符 char c;
以下讨论默认 c 为字母
我们知道小写字母的ASCII值比其大写字母的大32,因此我们通常采取下面两种方式转换字母大小写
c = c + 32;
把大写字母转换为小写c = c - 32;
把小写字母转换为大写
我们要把 c 转换为大写字母,如果一开始我们不知道 c 为大写还是小写,要对其转换的话,我们通常需要一个 if 语句判断一下 c 的大小写 如:if(c>='a'&&c<='z')
或者if(islower(c))
,然后才对其转换,一般需要两步。有没有更加高效的算法一步到位呢?当然是有的,而且还真和位有关,位运算!
我们先来看一眼具体操作:
c = c | 32;
利用或运算将这个字母转化为小写字母c = c & ~32;
利用与运算将这个字母转化为大写字母c = c ^ 32;
利用异或运算将字母大小写互换,即大写转小写,小写转大写
这样做的原理是什么呢?我们先来看一下字母的ASCII码值
大写 | 十进制 | 二进制 | 小写 | 十进制 | 二进制 |
---|---|---|---|---|---|
A | 65 | 0100 0001 | a | 97 | 0110 0001 |
B | 66 | 0100 0010 | b | 98 | 0110 0010 |
C | 67 | 0100 0011 | c | 99 | 0110 0011 |
… | |||||
Z | 90 | 0101 1010 | z | 122 | 0111 1010 |
通过观察我们发现,大写字母和其小写的二进制位只有在第5位(加粗部分)才出现不同,其他位都相同
因此,我们只需要改变二进制的第5位,其余位保持不变,就能实现字母大小写的转换,如何改变呢?当然得在那个不同的第5位二进制上面下功夫,利用8位二进制数0010 0000进行操作,它的十进制是32。
一个字母转换为对应小写字母,把这个字母的ASCII值和32按位进行或运算
以A和a为例:
- A(0100 0001) | 32(0010 0000) = a(0110 0001)
- a(0110 0001) | 32(0010 0000) = a(0110 0001)
一个字母转换为对应大写字母,把这个字母的ASCII值和 ~32 按位进行与运算,~32就是对32按位取反,32(0010 0000) ——> ~32(1101 1111)
以B和b为例:
扫描二维码关注公众号,回复:
15335078 查看本文章
- b(0110 0010) & ~32(1101 1111) = B(0100 0010)
- B(0100 0010) & ~32(1101 1111) = B(0100 0010)
字母大小写互换,大写转小写,小写转大写,把这个字母的ASCII值和32按位进行异或运算
以Z和z为例:
- Z(0101 1010) ^ 32(0010 0000) = z(0111 1010)
- z(0111 1010) ^ 32(0010 0000) = Z(0101 1010)
看了这些推导过程,相信你一定理解了上面的操作了,你也可以编写程序验证一下结果的正确性,以加深印象。如果你还有疑惑的地方,请在下方评论里发问。