首頁  >  問答  >  主體

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

比如:

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

这是为什么呢?
望点拨指教,谢谢!
ringa_leeringa_lee2714 天前784

全部回覆(6)我來回復

  • ringa_lee

    ringa_lee2017-04-17 13:34:10

    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
    ...

    回覆
    0
  • 黄舟

    黄舟2017-04-17 13:34:10

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

    回覆
    0
  • PHPz

    PHPz2017-04-17 13:34:10

    去試試:

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

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:34:10

    首先明確 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' 將小寫字母轉換成大寫字母。

    回覆
    0
  • 阿神

    阿神2017-04-17 13:34:10

    大寫與小寫差了32

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:34:10

    因為當時設計ASCII時,對字母進行編碼的時候,就編得非常有規律:

    1. 字母的編碼依照字母表中順序進行排序。

    2. 同一個字母的大小寫的編碼的距離相同。

    假設一開始ASCII的發明者抽風了,完全隨意編碼。那麼這個方法就不行了。
    另外,其實char型別也是一種整型,只不過它被設計成可以直接用字元字面量賦值罷了。

    回覆
    0
  • 取消回覆