s[i]^=32如何将大写转换为小写?

How does s[i]^=32 convert upper to lower case?

本文关键字:转换      更新时间:2023-10-16
int main()
{
    string s;
    cout << "enter the string :" << endl;
    cin >> s;
    for (int i = 0; i < s.length(); i++)
        s[i] ^= 32;
    cout << "modified string is : " << s << endl;
    return 0;
}

我看到这段代码在stackoverflow上将大写转换为小写。

但是我不明白s[i] = s[i]^32这句话。

它是如何工作的?

^=是异或赋值操作符。32在二进制中是100000,所以^= 32交换目的地的第5位。在ASCII中,小写字母和大写字母相隔32个位置,所以这将小写字母转换为大写字母,也可以反过来转换。

但是它只适用于ASCII,例如不适用Unicode,并且只适用于字母。为了编写可移植的c++,你不应该假设字符编码是ASCII,所以请不要使用这样的代码。

它是如何工作的?

让我们看看ASCII值'A':

'A'是二进制1000001

xoror with 32 (binary 100000)

产生任何值,如果上面的字符表示位没有设置:

1000001XOR100000= 1100001 == 'a'


任何正常和可移植的c或c++应用程序都应该使用tolower():

int main()
{
    string s;
    cout<<"enter the string :"<<endl;
    cin>>s;
    for (int i=0;i<s.length();i++) s[i] = tolower( (unsigned char)s[i] );
                                     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    cout<<"modified string is : "<<s<<endl;
    return 0;
}

s[i]=s[i]^32(货物崇拜)魔法,依赖于ASCII表特定映射到数字char值。

还有其他char代码表,例如EBCDIC,其中

 s[i]=s[i]^32

方法无法检索到相应的小写字母。


std::ctype::tolower()的参考文档页面中有一个更复杂的c++版本,可以将其转换为小写字符。

在c++中,像它的前身C一样,char是一个数字类型。毕竟,这是字符在硬件上的表示方式,这些语言不会向您隐藏这一点。

在ASCII中,字母有一个有用的属性,大写字母和小写字母之间的区别是一个二进制位:第5位(如果我们从0开始从右开始编号)。

大写A由字节0b01000001(十六进制的0x41)表示,小写A由字节0b01100001(十六进制的0x61)表示。注意,大写字母A和小写字母A之间的唯一区别是第5位。此模式从B延续到z

因此,当您对表示ASCII字符的数字执行^= 32(顺便说一下,它是2的5次方)时,它所做的是切换第5位-如果它是0,则变为1,反之亦然,这将字符从大写变为小写,反之亦然。