C 这个自定义toupper()函数是如何工作的?
我见过下面的程序使用自定义C 这个自定义toupper()函数是如何工作的?,c,toupper,C,Toupper,我见过下面的程序使用自定义toupper()函数 #include <stdio.h> void my_toUpper(char* str, int index) { *(str + index) &= ~32; } int main() { char arr[] = "geeksquiz"; my_toUpper(arr, 0); my_toUpper(arr, 5); printf("%s", arr); return 0
toupper()
函数
#include <stdio.h>
void my_toUpper(char* str, int index)
{
*(str + index) &= ~32;
}
int main()
{
char arr[] = "geeksquiz";
my_toUpper(arr, 0);
my_toUpper(arr, 5);
printf("%s", arr);
return 0;
}
#包括
void my_toUpper(char*str,int索引)
{
*(str+指数)&=~32;
}
int main()
{
char arr[]=“geeksquick”;
my_toUpper(arr,0);
my_toUpper(arr,5);
printf(“%s”,arr);
返回0;
}
这个函数究竟是如何工作的?我不明白背后的逻辑。如果有人能很容易地解释,那就好了 要将字母从小写转换为大写,需要从小写字母的ASCII值中减去32
对于代表小写字母的ASCII值,减去32等于ANDIN~32
。这就是我们正在做的事情
*(str + index) &= ~32;
它从str
中获取索引
第th个成员的值,减去32(按位和使用~32
,清除特定的位值),并将其存储回同一索引
FWIW,这是一种特殊情况,即“重置”特定位以获得实际减去32的结果。这种“减法”基于小写字母ASCII值的特定位表示在这里工作。正如评论中提到的,这不是一种一般的减法方法,因为这种“重置”逻辑对减法的任何值都不起作用
关于使用的
是按位和赋值的&=
不是按位的~
str
中存在的(in)有效值的错误检查。您需要注意这一点。接下来,要将字母从小写转换为大写,您需要从小写字母的ASCII值中减去32
对于代表小写字母的ASCII值,减去32等于ANDIN~32
。这就是我们正在做的事情
*(str + index) &= ~32;
它从str
中获取索引
第th个成员的值,减去32(按位和使用~32
,清除特定的位值),并将其存储回同一索引
FWIW,这是一种特殊情况,即“重置”特定位以获得实际减去32的结果。这种“减法”基于小写字母ASCII值的特定位表示在这里工作。正如评论中提到的,这不是一种一般的减法方法,因为这种“重置”逻辑对减法的任何值都不起作用
关于使用的
是按位和赋值的&=
不是按位的~
注意:此自定义函数缺少对
str
中存在的(in)有效值的错误检查。您需要注意这一点。要理解这一点,我们必须了解字母的ASCII表示形式。在base 2中最容易做到这一点
A 01000001 a 01100001
B 01000010 b 01100010
C 01000011 c 01100011
D 01000100 d 01100100
... ...
X 01011000 x 01111000
Y 01011001 y 01111001
Z 01011010 z 01111010
请注意,大写字母均以010
开头,小写字母均以011
开头。请注意,对于同一字母的大写和小写版本,低位都是相同的
因此:要将小写字母转换为相应的大写字母,我们只需将011
更改为010
,或者换句话说,关闭00100000
位
现在,关闭位的标准方法是对掩码进行逐位AND运算,在要关闭位的位置使用0,其他位置都使用1。所以我们想要的掩码是11011111
。我们可以将其写成0xdf
,但本例中的程序员选择通过编写~32
来强调它是00100000
的补充掩码。二进制中的32是00100000
这项技术工作得很好,只是它会对非字母做一些奇怪的事情。例如,它将把'{'
转换成'['
(因为它们分别有ASCII码011111011
和0010110111
)。它将把星号'*'
转换成新行'\n'
(00101010
转换成00001010
)
在ASCII中,将大写转换为小写的另一种方法是减去32。这也将把'a'
转换为'a'
(97到65,十进制),但if也会将'A'
转换为'!'
。在这种情况下,按位AND技术实际上是有利的,因为它将'A'
转换为'A'
(这是转换为大写例程应该做的)
底线是,无论你是用~32和还是减去32,在一个适当安全的函数中,你还必须检查被转换的字符是否是正确的字母类型
此外,值得注意的是,该技术完全采用7位ASCII字符集,不适用于其他字符集的重音或非罗马字母,如ISO-8859或Unicode(EBCDIC将是另一回事)要理解这一点,我们必须看看字母的ASCII表示法。最简单的方法是在基数2中
A 01000001 a 01100001
B 01000010 b 01100010
C 01000011 c 01100011
D 01000100 d 01100100
... ...
X 01011000 x 01111000
Y 01011001 y 01111001
Z 01011010 z 01111010
请注意,大写字母均以010
开头,小写字母均以011
开头。请注意,对于同一字母的大写和小写版本,小写位均相同
因此:要将小写字母转换为相应的大写字母,我们只需将011
更改为010
,或者换句话说,关闭00100000
位
现在,关闭一个位的标准方法是对一个掩码进行按位AND运算,其中0位于要关闭的位的位置,1位于其他位置。因此,我们想要的掩码是11011111
。我们可以将其写成0xdf
,但本例中的程序员选择强调它是0的补充掩码0100000
通过写入