为什么可以通过ASCII中的字母排序规则来进行字母的大小写转换?

monkeyRan
  • 240

比如:

通过a+'a'-'A' 将大写字母转换成小写字母
通过a+'A'-'a' 将小写字母转换成大写字母

这是为什么呢?
望点拨指教,谢谢!
回复
阅读 7.4k
6 个回答
manxisuo
  • 10.8k

因为当时设计ASCII时,对字母进行编码的时候,就编得非常有规律:

  1. 字母的编码按照字母表中顺序进行排序。

  2. 同一个字母的大小写的编码的距离相同。

假设一开始ASCII的发明者抽风了,完全随意编码。那么这个方法就不行了。
另外,其实char类型也是一种整型,只不过它被设计成可以直接用字符字面量赋值罢了。

IT_狗
  • 982

c/c++语言中为了区分值的不同用途,添加了类型的概念, 于是同样的值允许有不同的解释方式;

λ  ~/  cat a.cc
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, const char *argv[]) {

        char c = 0b01000001;
        int  i = 0b01000001;

        printf("char=%c\n", c);
        printf("int =%d\n", i);

        return EXIT_SUCCESS;
}

λ  ~/  g++ a.cc -Wall
λ  ~/  ./a.out 
char=A      #按照char来处理0b01000001会得到一个字符A
int =65     #按照int来处理0b01000001会得到一个数字65

c++在处理char之间的减法时, 是按照原始的byte内二进制数值进行运算; 所以'a'可以和'A'做数值的加减;
另外ASCII码表定义了一个具体值到人类可读字符的映射关系,参见ASCII表,你可以看到对应关系是按照字母表顺序定义好的, 而且在具体的值上a>A; 且a-A和b-B的差值是固定的, 任何一个大写字母在数值上加上这个差值刚好就能得到对应的小写字母的值.

二进制         十进制  十六进制        图形
01000001       65      41             A   #65->A
01000010       66      42             B   #66->B
01000011       67      43             C
01000100       68      44             D
...
01100001       97      61             a
01100010       98      62             b
01100011       99      63             c
01100100       100     64             d
...

a + 'a' - 'A'
'a'的ASCII是97,'A'的ASCII是65,所以上面这一行就等于 a + 97 - 65, 也就是 a + 32

mkwz
  • 2.7k

去试一试:

printf("ASCII of c is : %d\nASCII of C is : %d\n", 'c', 'C');
jaege
  • 2.5k

首先明确 C++ 中字符的概念,一个char类型的变量在实际存储时通常是一个8位的二进制数(即一个字节),所以支持各种数学运算。当你用'A'-'a'时,结果就是这两个字符对应的数值差。

而一个char与一个数字是怎么对应起来的呢?这就要说到 ASCII 字符表了,它明确了字符与数字之间的映射关系,每一个字符都一一对应于一个数字。部分 ASCII 字符表如下所示:

DEC    OCT    HEX    BIN       Symbol    Description
...
48    060    30    00110000    0         Zero
49    061    31    00110001    1         One
50    062    32    00110010    2         Two
...
56    070    38    00111000    8         Eight
57    071    39    00111001    9         Nine
...
65    101    41    01000001    A         Uppercase A
66    102    42    01000010    B         Uppercase B
67    103    43    01000011    C         Uppercase C
...
88    130    58    01011000    X         Uppercase X
89    131    59    01011001    Y         Uppercase Y
90    132    5A    01011010    Z         Uppercase Z
...
97    141    61    01100001    a         Lowercase a
98    142    62    01100010    b         Lowercase b
99    143    63    01100011    c         Lowercase c
...
120    170    78    01111000    x         Lowercase x
121    171    79    01111001    y         Lowercase y
122    172    7A    01111010    z         Lowercase z
...

不知道看完以后题主能发现规律吗?表中的字符09是连续分布的,AZ是连续分布的,az也是连续分布的。而且同一对大小写字母之间的距离是相同的,即'A'-'a',且大写在前,小写在后。

所以,可以通过通过 ch + 'a' - 'A' 将大写字母转换成小写字母,通过 ch + 'A' - 'a' 将小写字母转换成大写字母。

大写与小写之间差了32

宣传栏